• 架构设计与分布式


    1.常见的缓存策略有哪些,你们项目中用到了什么缓存系统,如何设计的。

    redis缓存,ehcache缓存


    2.分布式集群下如何做到唯一序列号。

    Redis生成,zk生成,只要保证原子性即可。


    3.设计一个秒杀系统,30 分钟没付款就自动关闭交易。

    秒杀系统设计理念

    限流:只有少部分消费者能真正传达到后台服务
    削峰:使用队列让流量均匀地进入系统,降低对系统的冲击
    异步处理:异步返回结果
    可用性:尽最大程度地保证高可用。
    用户体验:消费者点击抢购按钮后,无论是否能抢到商品,期望是能得到及时的反馈。

    自动关闭交易使用Redis的发布订阅机制,在失效后进行后续操作。


    4.如何使用 redis 和 zookeeper 实现分布式锁?有什么区别优缺点,分别适用什么场景。

    redis 适合性能要求高的场景,缺点是存放于内存,宕机后锁丢失。

    zk 可以有效的解决锁无法释放的问题,创建锁时,客户端会在 zk 创建一个临时节点,一旦客户端挂掉了,那这个临时节点就会自动删除,其他客户端可以再次获得锁。

    zk 可以默认实现 阻塞锁非阻塞锁 ,但 Redis 默认能实现 非阻塞锁 ,需要 阻塞锁 需要自己改造


    5.如果有人恶意创建非法连接,怎么解决。

    使用过滤器处理


    6.分布式事务的原理,优缺点,如何使用分布式事务。

    分布式事务通常分为两种:

    • TCC

      两阶段补偿型 (TCC)

      1. 主业务活动请求 ( try ) 各个从业务服务预留资源。 try 过程的本地事务,是保证资源预留的业务逻辑的正确性。

      2. 如果在第一阶段所有业务资源都预留成功,那么 confirm 各个从业务服务,否则取消( cancel )所有从业务服务的资源预留请求。

    • 2PC/3PC

      三阶段提交 (3PC)

      1. 协调者:接收事务请求并把 canCommit 发送给参与者

        参与者:向协调者发送Yes消息并切换到 prepared 状态

      2. 协调者:接收所有参与者的Yes消息,向所有参与者发送 preCommit 消息并切换到 prepared 状态

        参与者:收到 preCommit 消息,它将发送 ACK 消息并等待最后的提交或中止。

      3. 协调者:在收到来自大多数参与者的确认的情况下,协调者切换到 commit 状态。并向所有参与者发送 doCommit 请求。

        参与者:参与者接收到 doCommit 请求之后,执行正式的事务提交,并发送 ack 给协调者

    参考文章:https://www.cnblogs.com/dennyzhangdd/p/10580446.html#_label11_2


    7.什么是一致性 hash。


    8.如何设计建立和保持 100w 的长连接。

    服务器内核调优(tcp,文件数),客户端调优,框架选择(netty)


    9.什么是 paxos 算法。


    10.什么是 zab 协议。

    ZAB 是 Zookeeper 原子广播协议的简称,Zookeeper 是通过 Zab 协议来保证分布式事务的最终一致性。

    1. Zab协议原理
    • 发现 Discovery
    • 同步 Synchronization
    • 广播 Broadcast
    1. Zab协议内容

      Zab 协议包括两种基本的模式:崩溃恢复 和 消息广播

      协议过程

      当整个集群启动过程中,或者当 Leader 服务器出现网络中弄断、崩溃退出或重启等异常时,Zab协议就会 进入崩溃恢复模式,选举产生新的Leader。

      当选举产生了新的 Leader,同时集群中有过半的机器与该 Leader 服务器完成了状态同步(即数据同步)之后,Zab协议就会退出崩溃恢复模式,进入消息广播模式。

      这时,如果有一台遵守Zab协议的服务器加入集群,因为此时集群中已经存在一个Leader服务器在广播消息,那么该新加入的服务器自动进入恢复模式:找到Leader服务器,并且完成数据同步。同步完成后,作为新的Follower一起参与到消息广播流程中。

      协议状态切换

      当Leader出现崩溃退出或者机器重启,亦或是集群中不存在超过半数的服务器与Leader保存正常通信,Zab就会再一次进入崩溃恢复,发起新一轮Leader选举并实现数据同步。同步完成后又会进入消息广播模式,接收事务请求。

      保证消息有序

      在整个消息广播中,Leader会将每一个事务请求转换成对应的 proposal 来进行广播,并且在广播 事务Proposal 之前,Leader服务器会首先为这个事务Proposal分配一个全局单递增的唯一ID,称之为事务ID(即zxid),由于Zab协议需要保证每一个消息的严格的顺序关系,因此必须将每一个proposal按照其zxid的先后顺序进行排序和处理。

    参考文章:https://www.jianshu.com/p/2bceacd60b8a


    11.说说你平时用到的设计模式。

    1. 策略模式

      public class StrategyUse {
          public static void main(String[] args) {
              Strategy strategy = new Strategy(new WeiXinPay());
              PayInfo payinfo = strategy.payForSometh();
              System.out.println(payinfo.getPayType());
              //微信
          }
      }
      
    2. 单例模式

      1. 饿汉式
      private final static Singleton INSTANCE = new Singleton();
      
      private Singleton(){}
      
      public static Singleton getInstance(){
          return INSTANCE;
      }
      
      1. 普通的懒汉式 (线程不安全,不可用)
      private static Singleton instance = null;
      
      private Singleton() {
      }
      
      public static Singleton getInstance() {
          if (instance == null) {
              instance = new Singleton();
          }
          return instance;
      }
      
      1. 同步方法的懒汉式 (可用)
      private static Singleton instance = null;
      
      private Singleton() {
      }
      
      public static synchronized Singleton getInstance() {
          if (instance == null) {
              instance = new Singleton();
          }
          return instance;
      }
      
      1. 双重检查懒汉式 (可用,推荐)
      private static volatile Singleton instance;
      
      private Singleton() {}
      
      public static Singleton getInstance() {
          if (instance == null) {
              synchronized (Singleton.class) {
                  if (instance == null) {
                      instance = new Singleton();
                  }
              }
          }
          return instance;
      }
      
    3. 代理模式

      //代理类
      public class BuyHouseProxy implements BuyHouse {
      
          private BuyHouse buyHouse;
      
          public BuyHouseProxy(final BuyHouse buyHouse) {
              this.buyHouse = buyHouse;
          }
      
          @Override
          public void buyHosue() {
              System.out.println("买房前准备");
              buyHouse.buyHosue();
              System.out.println("买房后装修");
      
          }
      }
      //测试类
      public class ProxyTest {
          public static void main(String[] args) {
              BuyHouse buyHouse = new BuyHouseImpl();
              buyHouse.buyHosue();
              BuyHouseProxy buyHouseProxy = new BuyHouseProxy(buyHouse);
              buyHouseProxy.buyHosue();
          }
      }
      
    4. 模板模式

      //抽象做菜父类
      public abstract class DodishTemplate {    
          /**
          * 具体的整个过程
          */
          protected void dodish(){
              this.preparation();
              this.doing();
              this.carriedDishes();
          }
          /**
          * 备料
          */
          public abstract void preparation();
          /**
          * 做菜
          */
          public abstract void doing();
          /**
          * 上菜
          */
          public abstract void carriedDishes ();
      }
      
      //西红柿炒蛋
      public class EggsWithTomato extends DodishTemplate{
      
          @Override
          public void preparation() {
              System.out.println("洗并切西红柿,打鸡蛋。");
          }
      
          @Override
          public void doing() {
              System.out.println("鸡蛋倒入锅里,然后倒入西红柿一起炒。");
          }
      
          @Override
          public void carriedDishes() {
              System.out.println("将炒好的西红寺鸡蛋装入碟子里,端给客人吃。");
          }
      
      }
      //测试类
      public class App {
          public static void main(String[] args) {
              DodishTemplate eggsWithTomato = new EggsWithTomato();
              eggsWithTomato.dodish();
          }
      }
      

    12.Dubbo 的原理,数据怎么流转的,怎么实现集群,负载均衡,服务注册和发现。重试转发,快速失败的策略是怎样的。

    Dubbo 的原理

    1. 初始化过程细节 把服务装载到容器中,然后注册服务,类似Spring启动过程一样。
    2. 服务的提供方会向注册中心注册自己提供的服务。
    3. 消费者在启动时,就会向注册中心订阅自己所需要的服务。
    4. 如果服务提供方有数据变更等,注册中心将基于长连接的形式推送变更数据给消费者。

    数据怎么流转的


    怎么实现集群

    使用Cluster 实现集群

    dubbo根据注册中心获取服务信息,在通过集群负载均衡策略后获取服务信息。服务集群需要注意application name需要一致。


    负载均衡

    Random LoadBalance:随机,按权重比率设置随机概率。

    RoundRobin LoadBalance:轮循,按公约后的权重比率设置轮循比率。

    LeastActive LoadBalance:最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。

    ConsistentHash LoadBalance:一致性Hash,相同参数的请求总是发到同一提供者。当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。


    重试转发,快速失败的策略

    容错机制分为6种

    传播属性 描述
    Failover Cluster(默认) 失败自动切换,当出现失败,重试其它服务器
    Failfast Cluster 快速失败,只发起一次调用,失败立即报错。通常用于非幂等性的写操作,比如新增记录。
    Failsafe Cluster 失败安全,出现异常时,直接忽略。通常用于写入审计日志等操作。
    Failback Cluster 失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。
    Forking Cluster 并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过 forks="2" 来设置最大并行数。
    Broadcast Cluster 广播调用所有提供者,逐个调用,任意一台报错则报错 [2]。通常用于通知所有提供者更新缓存或日志等本地资源信息。

    在提供者中,reties的值设置在@Service中

    在消费者中,reties的值设置在@Reference中

    其中可以设置timeout进行超时重试


    13.一次 RPC 请求的流程是什么。

    1. 服务消费方调用服务
    2. 消费方接收到调用后把方法和参数组装成网路传输消息体
    3. 通过注册中心找到服务地址,并把消息发送到服务端
    4. 服务提供方收到消息后进行解码
    5. 服务提供方根据解码结果调用本地方法
    6. 本地方法把结果返回给服务提供方,并打包发送回消费方
    7. 消费方收到消息进行解码

    14.聊了下曾经参与设计的服务器架构。


    15.应用服务器怎么监控性能,各种方式的区别。

    Prometheus监控,使用exporter做数据指标的采集,grafana展示,后面会单独做一个部署的教程。


    16.如何设计一套高并发支付方案,架构如何设计。

    1. 防止重复提交、支付
    2. 防止用户同一商品购买两次
    3. 支付过程中防止订单交易状态过期
    4. 预热购物信息
    5. 把支付过程改为异步,加入请求队列,降低服务器压力


    17.如何实现负载均衡,有哪些算法可以实现。

    SpringCloud的Ribbon,还有dubbo的。
    Ribbon:https://www.cnblogs.com/nicori/p/11672030.html
    dubbo:问题12有解答。


    18.Zookeeper 的用途,选举的原理是什么。

    zk本质上是分布式的小文件存储系统,是一个分层的文件系统目录树结构,每个节点可以存储少量数据(1M左右),每个节点叫ZNode,通过路径作为唯一标识。

    1. 分布式锁服务
    2. 配置管理

    19.Mybatis 的底层实现原理。

    https://www.cnblogs.com/nicori/p/13533576.html


    20.请思考一个方案,实现分布式环境下的 countDownLatch。

    基于Redisson的分布式锁 RCountDownLatch 可以实现类似 countDownLatch 的效果


    21.后台系统怎么防止请求重复提交。

    https://my.oschina.net/huangweiindex/blog/1843927


    22.讲讲你理解的服务治理。


    23.如何做到接口的幂等性。

  • 相关阅读:
    oracle 11g SKIP_UNUSABLE_INDEXES参数
    oracle /*+ SYS_DL_CURSOR */ 这个hint
    各种存储的访问延时数量级备忘参考
    linux交换区使用过多导致的性能问题
    JSch : channel never closed or EOF 通道未关闭
    The Architecture of Open Source Applications: Berkeley DB
    vs变量监视提示-VAR-CREATE: UNABLE TO CREATE VARIABLE OBJECT解决方法
    centos 6.5 gdb 7.10安装make[5]: *** [install-bfdincludeHEADERS] Error 1解决
    oracle 11g禁用和强制direct path read
    sqlloader parallel调用报ORA-26002: table has index defined upon it.解决方法
  • 原文地址:https://www.cnblogs.com/nicori/p/14377989.html
Copyright © 2020-2023  润新知