Ribbon简介
Ribbon是Netflix下的负载均衡项目,它在集群中为各个客户端的通信提供了支持,主要实现中间层应用层析的负载均衡。Ribbon提供以下特性:
- 负载均衡器,可支持插拔式的负载均衡规则。
- 对多种协议提供支持,例如HTTP、TCP、UDP。
- 集成了负载均衡功能的客户端。
Spring Cloud将Ribbon的API进行了封装,使用者可以使用封装后的API来实现负载均衡,也可以直接使用Ribbon的原生API。
Ribbon主要有以下三大子模块:
- ribbon-core:该模块为Ribbon项目的核心,主要包括负载均衡器接口定义、客户端接口定义、内置的负载均衡实现等API。
- ribbon-eureka:为Eureka客户端提供的负载均衡实现类。
- ribbon-httpclient:对Apache的HttpClient进行封装,该模块提供了还有负载均衡功能的REST客户端。
负载均衡器组件
Ribbon的负载均衡器主要与集群中的各个服务器进行通信,负载均衡器需要提供以下基础功能:
- 维护服务器的IP、DNS名称等信息。
- 根据特定的逻辑在服务器列表中个循环。
为了实现负载均衡的基础功能,Ribbon的负载均衡器有以下三大子模块:
- Rule:一个逻辑组件,这些逻辑将会决定从服务器列表中返回哪个服务器实例。
- Ping:该组件主要使用定时器来确保服务器网络可以连接。
- ServerList:服务器列表,可以通过静态的配置确定负载的服务器,也可以动态指定服务器列表。如果动态指定服务器列表,则会有后台的线程来刷新该列表。
Ribbon的配置
除了使用ConfigurationManager在代码中指定配置项外,例如:
ConfigurationManager.getConfigInstance().setProperty(“my-client.ribbon.listOfServers”,”localhost:8080,localhost:8081”)
还可以将配置放到.properties或.yml文件中。属性配置格式如下:
<client>.<nameSpace>.<property>=<value>
其中<client>为客户端名称,声明该配置属于哪一个客户端,在使用ClientFactory时可传入客户端名称,即返回对应的“请求客户端”实例。<nameSpace>为该配置的命名空间,默认为ribbon,<property>位属性名,<value>位属性值。如果相对全部客户端生效,可以将客户端名称去掉,直接以<nameSpace>.<property>的格式进行配置。
ConfigurationManager的loadPropertiesFromResources方法可以指定properties文件位置。
负载均衡机制
Ribbon的负载均衡器接口定义了服务器的操作,主要用于服务器的选择。在默认情况下会使用RoundRobinRule的规则逻辑。
自定义负载规则
如果想自定义负载均衡规则,可以编写一个IRule接口的实现类。在自定义规则类中,实现的choose方法调用了ILoadBalancer的getAllServers方法,返回全部服务器。可以根据自己业务规则返回指定的服务器。然后在客户端代码中调用负载均衡器的setRule(new MyRule(lb))设置负载规则为我们自定义的负载规则。
也可以使用配置的方式来完成这些工作,修改ribbon的配置,如:
ConfigurationManager.getConfigInstance().serProperty(“my-client.ribbon.NFLoadBalancerRuleClassName”, MyRule.class.getName())
或者在配置文件在配置:
my-client.ribbon.NFLoadBalancerRuleClassName=com.xx.xxxx.MyRule
Ribbon自带的负载规则
Ribbon提供了若干个内置的负载规则,使用者完全可直接使用,主要有以下内置的负载规则:
- RoundRobinRule:系统默认的规则,通过简单的轮询服务列表来选择服务器,其他规则在很多情况下仍然使用RoundRobinRule。
- AvailabilityFilteringRule:该规则会忽略以下服务器。
- 无法连接的服务器:在默认情况下,如果3次连接失败,该服务器将会被置为“短路”的状态,该状态将持续30秒;如果再次连接失败,“短路”状态的持续时间将会以几何级数增加。可以通过修改niws.loadbalancer.<clientName>.connectionFailureCountThreshold属性,来配置连接失败的次数。
- 并发数过高的服务器:如果连接到该服务器的并发数过高,也会被这个规则忽略,可以通过修改<clientName>.ribbon.ActiveConnectionsLimit属性来设定最高并发数。
- WeightedResponseTimeRule:为每个服务器授予一个权重值,服务器的响应时间越长,该权重值就越少,这个规则会随机选择服务器,权重值有可能会决定服务器的选择。
- ZoneAvoidanceRule:该规则以区域、可用服务器为基础进行服务器选择。使用Zone对服务器进行分类,可以理解为机架或者机房。
- BestAvailableRule:忽略“短路”的服务器,并选择并发数较低的服务器。
- RandomRule:顾名思义,随机选择可用的服务器。
- RetryRule:还有重试的选择逻辑,如果使用RoundRobinRule选择的服务器无法连接,那么将会重新选择服务器。
Ping机制
在负载均衡器中,提供了Ping机制,每隔一段时间,会去Ping服务器,判断服务器是否存活。该工作由IPing接口的实现类负责,如果单独使用Ribbon,在默认情况下,不会激活Ping机制,默认的实现类为DummyPing。
可以在代码中使用负载均衡器的.setPing(IPing iPing)方法来设置Ping机制,使用.setPingInterval(int interval)来设置Ping操作的时间间隔。
还可以在配置类中是设置IPing实现类
ConfigurationManager.getConfigInstance().setProperty(“my-client.ribbon.NFLoadBalancerPingClassName”,PingUrl.class.getName())
设置Ping的时间间隔
ConfigurationManager.getConfigInstance().setProperty(“my-client.ribbon.NFLoadBalancerPingInterval”,2)
或在配置文件中配置。
自定义Ping
实现自定义Ping较为简单,先实现IPing接口,然后再通过配置来设定具体的Ping实现类。
其他配置
- NFLoadBalancerClassName:指定负载均衡器的实现类,可利用该配置实现自己的负载均衡器。
- NIWSServerListClassName:服务器列表处理类,用来维护服务器列表,Ribbon已经实现动态服务器列表。
- NIWSServerListFilterClassName:用于处理服务器列表拦截。
在Spring Cloud中使用Ribbon
Spring Cloud集成了Ribbon,结合Eureka,可实现客户端的负载均衡。