面试题答案
一键面试Dubbo常用负载均衡策略实现原理
- 随机(Random)
- 原理:Dubbo会基于权重在所有可用的服务实例中随机选择一个。每个服务实例都有一个权重值,权重越大,被选中的概率越高。Dubbo通过计算总权重,然后生成一个在0到总权重之间的随机数,根据这个随机数落在哪个实例权重区间来决定选择哪个实例。例如,有三个实例A、B、C,权重分别为1、2、3,总权重为6。随机生成一个0 - 5之间的数,如果是0,选A;如果是1、2,选B;如果是3、4、5,选C。
- 轮询(RoundRobin)
- 原理:按照顺序依次将请求分配到每个服务实例上。Dubbo维护一个计数器,每次请求到来时,计数器加1,然后对实例总数取模,根据取模结果选择对应的实例。例如,有三个实例A、B、C,第一次请求计数器为1,1 % 3 = 1,选择A;第二次请求计数器为2,2 % 3 = 2,选择B;第三次请求计数器为3,3 % 3 = 0,选择C,以此类推。如果实例有权重,会按照权重比例分配请求,而不是简单的顺序分配。
- 最少活跃调用数(LeastActive)
- 原理:Dubbo会统计每个服务实例的活跃调用数,优先将请求分配给活跃调用数最少的实例。活跃调用数表示当前正在处理的请求数量,活跃调用数少意味着该实例相对空闲,有更多资源来处理新的请求。如果有多个实例的活跃调用数相同,则会参考权重,选择权重较大的实例,计算方式同随机负载均衡基于权重的选择方式。
- 一致性哈希(ConsistentHash)
- 原理:Dubbo先对服务实例的地址等信息进行哈希计算,得到一个哈希值,将其映射到一个环形的哈希空间上。当有请求到来时,对请求参数(一般是请求的唯一标识)进行同样的哈希计算,得到请求的哈希值,也映射到这个环形空间上。然后从这个请求的哈希值位置开始,顺时针寻找第一个服务实例节点,将请求分配给该实例。这样可以保证相同参数的请求总是被路由到同一个实例上,有利于提高缓存命中率等。如果某个实例节点失效,只会影响该节点在哈希环上顺时针相邻的部分请求,而不会影响其他大部分请求的路由。
Dubbo容错机制工作原理
- 失败重试(Failover)
- 原理:当一次服务调用失败时,Dubbo会自动重试其他可用的服务实例。默认重试次数为2次(可配置),也就是说,加上第一次调用,总共会尝试调用3次。Dubbo会按照负载均衡策略(如随机、轮询等)重新选择实例进行调用。例如,第一次调用实例A失败,Dubbo会根据负载均衡策略选择实例B进行第二次调用,如果还是失败,再选择实例C进行第三次调用。这种机制适用于读操作或者对调用结果一致性要求不高的场景,因为多次重试可能会导致重复操作。
- 快速失败(Failfast)
- 原理:当服务调用失败时,立即抛出异常,不再进行重试。这种机制适用于对响应时间敏感,且不允许有重试操作的场景,比如支付操作。如果支付调用失败,不应该重试,因为重试可能导致重复支付,应直接返回错误信息给用户。
- 失败安全(Failsafe)
- 原理:当服务调用失败时,Dubbo会忽略异常,返回一个空结果或者默认值。这种机制适用于对结果准确性要求不高,且不希望因为局部错误影响整体流程的场景,例如统计日志记录等操作。即使记录失败,也不影响主要业务流程继续执行。
- 失败自动恢复(Failback)
- 原理:当服务调用失败时,Dubbo会将失败的请求记录到一个定时任务队列中,由一个后台线程定时重试这些失败的请求。这种机制适用于对调用可靠性要求较高,但对响应时间不敏感的场景,比如异步消息发送。即使消息发送失败,也可以在后续重试,保证消息最终能被发送出去。
- 并行调用(Forking)
- 原理:Dubbo会同时调用多个服务实例,只要有一个实例成功返回结果,就立即返回该结果,忽略其他正在进行的调用。可以通过配置并行调用的实例个数来控制并发度。这种机制适用于对响应时间要求极高,且允许一定资源消耗的场景,比如实时性要求高的查询操作,通过并行调用多个实例,以最快返回结果的实例为准。
根据业务需求选择合适的负载均衡和容错策略
- 负载均衡策略选择
- 随机:适用于大多数无状态服务,当服务实例性能差异不大时,随机策略能简单有效地分配请求,避免单个实例压力过大。例如,一些简单的接口查询服务,各个实例处理能力相当,可采用随机策略。
- 轮询:适合服务实例性能较为一致的场景,能保证每个实例都有机会处理请求,实现较为均匀的负载分配。比如一组配置相同的文件存储服务实例。
- 最少活跃调用数:适用于服务实例处理请求的时间差异较大的场景,能将请求优先分配给空闲实例,提高整体处理效率。例如,有些实例处理复杂业务逻辑耗时较长,而有些处理简单业务逻辑耗时短,使用最少活跃调用数策略可更好地平衡负载。
- 一致性哈希:适用于需要保证相同请求始终路由到同一实例的场景,如缓存服务,可提高缓存命中率。如果业务中有对特定用户或数据的持久化连接需求,也可采用一致性哈希策略。
- 容错策略选择
- 失败重试:适合读操作,如数据库查询,重试一般不会带来严重后果,且能提高调用成功率。对于一些非关键业务的写操作,如果允许重复执行,也可使用失败重试。
- 快速失败:用于对响应时间敏感且不允许重试的操作,如支付、下单等关键业务操作,避免重复操作带来的风险。
- 失败安全:适用于对结果准确性要求不高,不影响整体业务流程的操作,如日志记录、监控数据上报等。
- 失败自动恢复:适用于对可靠性要求高但对响应时间不敏感的异步操作,如消息队列的消息发送,确保消息最终能成功发送。
- 并行调用:适用于实时性要求极高的查询操作,如实时行情查询等,通过并行调用多个实例获取最快响应。