SpringCloud - 04负载均衡Ribbon
(1)负载均衡简介
负载均衡LB(Load Balance): 将用户的请求平摊的分配到多个服务上,从而达到系统的HA。
常见负载均衡有软件Nginx、LVS, 硬件F5等。在中间件 Dubbo和SpringCloud均提供了负载均衡,SpringCloud可自定义负载均衡算法。
集中式LB: 在服务的消费方和提供方之间使用独立的LB设施,由该设施负责把访问请求通过某种策略转发至服务的提供方。
进程内LB: 将LB逻辑集成到消费方,消费方从服务注册中心获取有哪些地址可用,然后再从这些地址中选择出一个合适的服务器。

Spring Cloud Ribbon 是基于Netflix Ribbon实现的一套客户端负载均衡的工具。
Ribbon客户端组件提供一系列完善的配置项,如连接超时、重试等。
在配置文件中列出Load Balancer后面所有的机器,Ribbon自动基于某种规则(简单轮询、随机连接等)去连接这些机器。
Ribbon在工作时分为两步
第一步: 选择Eureka Server, 优先选择在同一个区域内负载较少的server。
第二步: 根据用户指定的策略,再从server取到的服务注册列表中选择一个地址。
(2)部署构建Consumer
(2.1)修改POM文件
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
(2.2)修改application.yml
eureka:
client:
service-url:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
instance:
instance-id: microservice-dept-consumer
prefer-ip-address: true
(2.3)添加注解@LoadBalanced
@Configuration public class ConfigBean { @Bean @LoadBalanced public RestTemplate getRestTemplate(){ return new RestTemplate(); } }
(2.4)修改主启动类
@SpringBootApplication @EnableEurekaClient public class DeptConsumerApplication {}
(2.5)修改客户端访问类Controller
@RestController public class DeptConsumerController { // private final static String REST_DEPT_URL_PREFIX ="http://localhost:8001"; private final static String REST_DEPT_URL_PREFIX ="http://MICROSERVICECLOUD-DEPT-PROVIDER"; }
(2.6)开启多个Provider

spring:
application:
name: microservicecloud-dept-provider // 3个服务提供者一致
eureka:
client:
service-url:
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka,http://eureka7003.com:7003/eureka
instance:
instance-id: microservice-dept-provider2
prefer-ip-address: true
(2.7)测试: 先启动Eureka集群,然后启动 provider, 再启动 consumer

总结: Ribbon就是一个软负载均衡的客户端组件,可以和其他所需请求的客户端结合使用,不仅仅只是与Eureka结合。
(3)负载均衡算法
IRule: 根据特定算法,从服务列表中选取一个要访问的服务
- RoundRobinRule: 轮询
- RandomRule: 随机
- AvailabilityFilteringRule: 会先过滤由于多次访问故障而处于断路器跳闸状态的服务,还有并发的连接数量超过阈值的服务,
- 然后对剩余的服务列表按照轮询策略进行
- WeightedResponseTimeRule: 根据平均响应时间计算所有服务的权重,响应时间越快服务权重越大,被选中可能越大。
- 刚启动时如果统计信息不足,则使用RoundRobinRule策略,等统计信息足够会切换到WeightedResponseTimeRule。
- RetryRule: 先按照RoundRobinRule的策略获取服务,获取服务失败则在指定时间内进行重试,获取可用服务。
- BestAvailableRule: 先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的
- ZoneAvoidanceRule: 默认规则,复合判断server所在区域的性能和server的可用性选择服务器
(3.1)配置负载均衡算法
@Configuration public class ConfigBean { // 省略其他代码 @Bean public IRule myRule(){ return new RandomRule(); // return new RoundRobinRule(); } }
(3.2)自定义负载均衡算法
(3.2.1)负载均衡算法: 轮询策略,每个服务器要求被调用5次。
public class RandomRule_ZY extends AbstractLoadBalancerRule { public void initWithNiwsConfig(IClientConfig iClientConfig) { } private int total = 0; // 总共被调用的次数,目前要求每台被调用5次 private int currentIndex = 0; // 当前提供服务的机器号 public Server choose(ILoadBalancer lb, Object key) { if(lb == null){ return null; } Server server = null; while (server == null){ if (Thread.interrupted()){ return null; } List<Server> upList = lb.getReachableServers(); List<Server> allList = lb.getAllServers(); int serverCount = allList.size(); if (serverCount == 0){ return null; } if (total < 5){ server = upList.get(currentIndex); total++; }else { total = 0; currentIndex++; if (currentIndex >= upList.size()){ currentIndex = 0; } } } return server; } public Server choose(Object key) { return choose(getLoadBalancer(), key); } }
(3.2.2)配置类
@Configuration public class MySelfRule { @Bean public IRule myRule(){ return new RandomRule_ZY(); } }
注意: 这个自定义配置类不能放在@ComponentScan所扫描的当前包下以及子包下,否则配置类会被所有Ribbon客户端共享,起不到特殊定制目的。
(3.2.3)主启动类: 在启动该微服务时加载自定义Ribbon配置类,使配置生效。
@SpringBootApplication @EnableEurekaClient @RibbonClient(name="MICROSERVICECLOUD-DEPT-PROVIDER", configuration = MySelfRule.class) public class DeptConsumerApplication {


浙公网安备 33010602011771号