Ribbon负载均衡及其应用 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中通过Ribbon提供的@LoadBalanced注解开启了客户端负载均衡。操作很简单,那如何实现的呢?
对于一个客户端负载均衡实现方案来说,核心有如下3部分:
1、服务发现:能够自动发现所依赖服务的列表。
2、服务监听:能够监测到失效的服务,并高效地将失效服务从服务列表中剔除。
3、服务选择策略:也就是负载均衡策略,能够决定如何在多个服务实例中选择一个有效的服务实例并进行相应的服务请求处理。
Ribbon作为作为Spring Cloud中客户端负载均衡实现方案,在实现原理上是不是如上述一致呢?具体看看,如下:
1、服务器列表(ServerList)
服务器列表就是客户端负载均衡所使用的个服务的服务实例列表。Ribbon在实现上支持3中服务器列表方式:
1)静态服务器列表:可以通过Ribbon中的BaseLoadBalancer所提供的setServersList()方法直接进行设置。
2)基于配置的服务器列表:需要在项目配置文件中通过.ribbon.listOfServers属性进行设置。如下:
userservicer.ribbon.listOfServers=http://XXX, http://XXX, http://XXX
3)基于服务发现的服务器列表:当我们在应用中同时使用Ribbon和Eureka时,默认就会使用该种方式,在应用启动时Ribbon就会从Eureka服务器中获取所有注册服务的列表数据,并保持同步。
2、服务器列表过滤器(ServerListFilter)
当开发者使用动态服务器列表时,该组件会对原始服务列表使用一定策略进行过滤,并返回有效的服务器列表给客户端负载均衡器使用。Ribbon在具体实现上提供以下可用过滤器工开发者在应用中进行选择。
1)ZoneAffinityServerListFilter:该过滤器基于区域感知的方式,实现对服务实例过滤,仅返回与本身所处区域一致的服务提供者实例列表。
2)ServerListSubsetFilter:该过滤器继承自ZoneAffinityServerListFilter,在进行区域感知过滤后,仅返回一个固定大小的服务列表,也就是说不会返回全部符合条件的服务实例列表。这种过滤器非常适用于拥有大规模服务器集群的系统。默认将返回20个服务实例,但可以通过ribbon.ServerListSubsetFilter.size属性设置具体返回的服务实例个数。
3)ZonePreferenceServerListFilter:是Spring Cloud整合Netflix时新增的一个过滤器。当开发者使用Spring Cloud整合Eureka和Ribbon时就会默认使用该过滤器。其主要是实现通过配置或者Eureka所属区域来过滤出同区域的服务实例列表。
3、服务实例存活探测(IPing)
这个很像ping指令,用来监测一个微服务实例是否有响应。Ribbon通过该组件来判断所持有的服务实例列表中的各服务可用情况,如果监测到某服务实例不再可用则会从列表中及时剔除。默认实现如下:
1)PingUrl:通过定期访问指定的URL,来判断服务器是否可用。
2)PingConstant:不做任何处理,只是返回一个固定值,用来标识该服务器是否可用。默认值为true,即可用。
3)NoOpPing:不做任何处理,直接返回true,表示该服务器可用,这是默认策略。
4)DummyPing:直接返回true,但实现了initWithNiwsConfig方法。
5)NIWSDiscoveryPing:根据DiscoveryEnabledServer中InstanceInfo的InstanceStatus属性判断,如果该属性的职位InstanceStatus.UP,则表示服务器可用,否则不可用。
4、负载均衡策略(IRule)
该部分负责选择一个最终服务实例地址作为负责均衡处理结果。Ribbon提供的选择策略有轮询、根据响应事件加权、断路器(当Hystix可用时)等。
5、负载均衡器(ILoadBalancer)
Ribbon负载均衡的具体实现主要是通过LoadBalancerClient类来实现的,而LoadBalancer又将具体处理委托给ILoadBalancer来处理。对于ILoadBalancer,可以理解客户端负载均衡“大总管”,其通过配置IRule、IPing等信息,并通过ServerList获取服务器注册列表的信息,默认以每10秒的频率向服务列表中每一个服务实例发送ping请求,进程服务实例是否仍存活,最后使用负载均衡策略对ServerListFilter过滤得到最终可用的服务实例列表进行处理并获取到最终要调用的服务实例,然后就可以交给服务调用器进行调用。
6、服务调用器(RestClient)
服务调用器也就是负责均衡后,Ribbon想服务提供者发起REST请求的工具。
Ribbon提供6大组件及相应功都是为负载均衡提供支持,那为何当在RestTemplate增加了@LoadBalance注解和就可以为服务嗲用开启负责均衡处理了呢?这个就是拦截器LoadBancerInterceptor的功劳了。具体可以如下图:
当给RestTemplate增加了@LoadBalance后,LoadLoadBalanceconfiguration就会对该RestTemplate进行处理——在RestTemplate的拦截器表中添加一个LoadBalancerInterceptor拦截器。当通过RestTemplate进行服务请求时LoadBalancerInterceptor中的拦截器方法就会启动,通过LoadBalanceClient使请求具有负责均衡功能。