1.LoadBalancerClient:负载平衡器客户端
(1)Riibon中一个非常重要的组件LoadBalancerClient,它作为负载均衡的一个客户端
<1>LoadBalancerClient在spring-cloud-commons包下
<2>LoadBalancerClient是一个接口,它继承ServiceInstanceChooser
<3>它的实现类是RibbonLoadBalancerClient
(2)LoadBalancerClient接口,有如下三个方法:
<1>excute()为执行请求
<2>reconstructURI()用来重构url
<3>代码示例如下:
public interface LoadBalancerClient extends ServiceInstanceChooser {
<T> T execute(String serviceId, LoadBalancerRequest<T> request) throws IOException;
<T> T execute(String serviceId, ServiceInstance serviceInstance, LoadBalancerRequest<T> request) throws IOException;
URI reconstructURI(ServiceInstance instance, URI original);}
(3)ServiceInstanceChooser接口,主要有一个方法:
<1>用来根据serviceId来获取ServiceInstance
<2>代码示例如下:
public interface ServiceInstanceChooser {
ServiceInstance choose(String serviceId);}
(4)LoadBalancerClient的实现类为RibbonLoadBalancerClient
<1>最终的负载均衡的请求处理,由RibbonLoadBalancerClient来执行
2.DynamicServerListLoadBalancer:动态服务器列表负载平衡器
(1)DynamicServerListLoadBalancer的继承类为BaseLoadBalancer
(2)DynamicServerListLoadBalancer是对基础负载均衡器的扩展,实现了两个功能
<1>服务实例在运行期间的动态更新
<2>对服务器实例清单的过滤功能,可以通过过滤器来选择地获取一批服务实例清单
(3)BaseLoadBalancer类,它默认的情况下,实现了以下配置:
<1>IClientConfig接口:DefaultClientConfigImpl配置
1.1. 用于对客户端或者负载均衡的配置
1.2.它的默认实现类为DefaultClientConfigImpl
<2>IRule接口:RoundRobinRule 路由策略
2.1.用于复杂均衡的策略
2.2.它有三个方法示例如下:
public interface IRule{
public Server choose(Object key);//根据key 来获取server
//设置ILoadBalancer
public void setLoadBalancer(ILoadBalancer lb);
//获取ILoadBalancer
public ILoadBalancer getLoadBalancer();}
<3>IPing接口:DummyPing
3.1.是用来向server发生”ping”,来判断该server是否有响应
3.2.从而判断该server是否可用,它有一个isAlive()方法,示例如下:
public interface IPing {
public boolean isAlive(Server server);}
3.3.IPing的实现类有5个
3.3.1.PingUrl:真实的去ping 某个url,判断其是否alive
3.3.2.PingConstant:固定返回某服务是否可用,默认返回true,即可用
3.3.3.NoOpPing:不去ping,直接返回true,即可用
3.3.4.DummyPing:直接返回true,并实现了initWithNiwsConfig方法
3.3.5.NIWSDiscoveryPing:
3.3.5.1.根据DiscoveryEnabledServer的InstanceInfo的InstanceStatus去判断
3.3.5.2.如果为InstanceStatus.UP,则为可用,否则不可用
<4>ServerList接口:ConfigurationBasedServerList
4.1.定义获取所有的server的注册列表信息的接口
4.2.它的代码示例如下:
public interface ServerList<T extends Server> {
public List<T> getInitialListOfServers();
public List<T> getUpdatedListOfServers();}
<5>ServerListFilter接口:ZonePreferenceServerListFilter
5.1.定义可根据配置去过滤或者根据特性动态获取符合条件的server列表的方法
5.2.代码示例如下:
public interface ServerListFilter<T extends Server> {
public List<T> getFilteredListOfServers(List<T> servers);}
<6>ILoadBalancer接口:ZoneAwareLoadBalancer
6.1.主要是实现动态的服务列表特性接口
6.2.代码示例如下:
public interface ILoadBalancer {
//增加服务实例
public void addServers(List<Server> newServers);
//某种策略 选中一个实例
public Server chooseServer(Object key);
//某私立停止服务
public void markServerDown(Server server);
//获取所有正常服务
public List<Server> getReachableServers();
//获取所有服务
public List<Server> getAllServers();}
4.Ribbon作为负载均衡执行流程
(1)负载均衡器是从EurekaClient获取服务信息
<1>每10秒钟,向EurekaClient发送一次”ping”
(2)并根据IRule去路由,并且根据IPing去判断服务的可用性
<1>根据pingerStrategy.pingServers(ping, allServers)获取服务的可用性
<2>如果该返回结果,如之前相同,则不去向EurekaClient获取注册列表
<3>如果不同则通知ServerStatusChangeListener或者changeListeners发生了改变,进行更新或者重新拉取
(3)LoadBalancerClient是在初始化的时候,会向Eureka获取服务注册列表
(4)LoadBalancerClient有了这些服务注册列表,就可以根据具体的IRule来进行负载均衡
5.总结
(1)Ribbon的负载均衡,主要通过LoadBalancerClient来实现的
(2)LoadBalancerClient具体交给了ILoadBalancer来处理
(3)ILoadBalancer通过配置IRule、IPing等信息,并向EurekaClient获取注册列表的信息
<1>默认10秒一次向EurekaClient发送“ping”,进而检查是否更新服务列表
<2>最后,得到注册列表后,ILoadBalancer根据IRule的策略进行负载均衡
(4)RestTemplate被@LoadBalance注解后,能实现负载均衡
<1>主要是维护了一个被@LoadBalance注解的RestTemplate列表
<2>并给列表中的RestTemplate添加拦截器,进而交给负载均衡器去处理