带你了解 Ribbon 负载均衡器的实现
Spring Cloud 中 Ribbon有在 Zuul 和 Feign 中使用,当然也可以通过在RestTemplate的 bean 定义上添加@LoadBalanced注解方式获得一个带有负载均衡更能的RestTemplate。
不过实现的方法都大同小异:对HttpClient进行封装,加上实例的”选择“(这个选择的逻辑就是我们所说的负载均衡)。
要学习某个框架的时候,最简单的方案就是:Running+Debugging。
跑就是了。
debug 不一定是为了 bug
debug 出真知
Debugging = Learning
选用 Ali Spittel 的一条推文:

以 Zuul 路由的线程栈为例

调整下顺序:
RetryableRibbonLoadBalancingHttpClient#execute(RibbonApacheHttpRequest, IClientConfig)
RetryableRibbonLoadBalancingHttpClient#executeWithRetry(...)
RetryTemplate#execute(RetryCallback<T, E>, RecoveryCallback<T>)
RetryTemplate#doExecute(RetryCallback<T, E>, RecoveryCallback<T>, RetryState)
RetryTemplate#canRetry(RetryPolicy, RetryContext)
InterceptorRetryPolicy#canRetry(RetryContext)
AbstractLoadBalancingClient#choose(String serviceId)
ZoneAwareLoadBalancer#chooseServer(Object key) //key as serviceId
BaseLoadBalancer#chooseServer(Object key)
PredicateBasedRule#choose(Object key)
AbstractServerPredicate#chooseRoundRobinAfterFiltering(List<Server> servers, Object loadBalancerKey)
AbstractServerPredicate#apply(Predicate)
分析
Zuul 收到请求经过一系列 Filter 的处理,来到 RibbonRoutingFilter;将请求封装成 RibbonCommandContext,然后使用 context 构建 RibbonCommand。最终调用RibbonCommand#execute()方法,将请求路由到下游。





[图片来自 https://www.facebook.com/sequenceprocess/]