求合伙人做网站/下载百度到桌面上
一、什么是Spring Cloud Ribbon?
- Spring Cloud Ribbon 是Spring Cloud Netflix 子项目的核心组件之一,主要给服务间调用及API网关转发提供负载均衡的功能。
- 在微服务架构中,很多服务都会部署多个,其他服务去调用该服务的时候,如何保证负载均衡是个不得不去考虑的问题。负载均衡可以增加系统的可用性和扩展性,当我们使用RestTemplate来调用其他服务时,Ribbon可以很方便的实现负载均衡功能。
- Ribbon 的客户端组件提供一系列完整的配置项如:连接超时、重试等等。简单的说,就是在配置文件中列出LoadBalancer后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等等)去连接这些机器,我们也很容易使用Ribbon实现自定义的负载均衡算。
- 负载均衡简单分类:
集中式LB
:即在服务的消费方和提供方之间使用独立的LB设施,如反向代理服务器,由该设施负责把访问请求通过某种策略转发至服务的提供方。进程式LB
:将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选出一个合适的服务器。
- Ribbon就属于进程内LB,它只是一个类库,集成于消费方进程,消费方通过它来获取到服务提供方的地址。
二、案例演示
-
添加依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId><version>2.2.0.RELEASE</version> </dependency> <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-ribbon</artifactId><version>2.2.0.RELEASE</version> </dependency>
-
添加配置
启动类
@SpringBootApplication @EnableEurekaClient public class RibbonClientApplication {public static void main(String[] args) {SpringApplication.run(RibbonClientApplication.class, args);} }
自定义配置类
@Configuration public class MyConfig {@Bean@LoadBalancedpublic RestTemplate restTemplate(){return new RestTemplate();} }
application.yml文件
server:port: 8080servlet:context-path: /spring:application:name: ribbon-clienteureka:client:register-with-eureka: falsefetch-registry: trueservice-url:defaultZone: http://localhost:8010/eureka# 服务访问地址 user-service-url: http://ribbon-service/
-
测试使用
-
编写控制器类
@RestController public class UserController {@Autowiredprivate RestTemplate restTemplate;@Value("${user-service-url}")private static String SERVICE_URL;@GetMapping("/get/{id}")public Map<String, Object> getUser(@PathVariable Long id){Map result = restTemplate.getForObject(SERVICE_URL + "get/" + id, Map.class);return result;}@GetMapping("/add")public Map<String, Object> addUser(User user){Map result = restTemplate.postForObject(SERVICE_URL + "add", user, Map.class);return result;} }
-
访问
访问:http://localhost:8010/
访问:http://localhost:8080/get/1
发现Ribbon默认采用轮询算法依次在每一个服务方进行访问
-
三、负载均衡策略
-
已定义的策略
Ribbon默认使用的是轮询算法
-
com.netflix.loadbalancer.RandomRule
:从提供服务的实例中以随机的方式;
-
com.netflix.loadbalancer.RoundRobinRule
:以线性轮询的方式,就是维护一个计数器,从提供服务的实例中按顺序选取,第一次选第一个,第二次选第二个,以此类推,到最后一个以后再从头来过;
-
com.netflix.loadbalancer.RetryRule
:在RoundRobinRule的基础上添加重试机制,即在指定的重试时间内,反复使用线性轮询策略来选择可用实例;
-
com.netflix.loadbalancer.WeightedResponseTimeRule
:对RoundRobinRule的扩展,响应速度越快的实例选择权重越大,越容易被选择;
-
com.netflix.loadbalancer.BestAvailableRule
:选择并发较小的实例;
-
com.netflix.loadbalancer.AvailabilityFilteringRule
:先过滤掉故障实例,再选择并发较小的实例;
-
com.netflix.loadbalancer.ZoneAwareLoadBalancer
:采用双重过滤,同时过滤不是同一区域的实例和故障实例,选择并发较小的实例。
-
-
自定义均衡策略
-
启动类添加注解
@SpringBootApplication @EnableEurekaClient @RibbonClient(name = "ribbon-service", configuration = RuleConfig.class) public class RibbonClientApplication {public static void main(String[] args) {SpringApplication.run(RibbonClientApplication.class, args);} }
-
自定义配置类
public class MyRule extends AbstractLoadBalancerRule {public MyRule() {}private int total = 1;private int current = 0;@SuppressWarnings({"RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE"})public Server choose(ILoadBalancer lb, Object key) {if (lb == null) {return null;} else {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 <= 3){server = upList.get(current);total++;}else{total = 1;current += 1;if(current > upList.size()-1){current = 0;}server = upList.get(current);}//-******************************if (server == null) {Thread.yield();} else {if (server.isAlive()) {return server;}server = null;Thread.yield();}}return server;}}protected int chooseRandomInt(int serverCount) {return ThreadLocalRandom.current().nextInt(serverCount);}public Server choose(Object key) {return this.choose(this.getLoadBalancer(), key);}public void initWithNiwsConfig(IClientConfig clientConfig) {} }
@Configuration public class RuleConfig {@Beanpublic IRule myRule(){return new MyRule();} }
-
五、常用配置
-
全局配置
ribbon:ConnectTimeout: 1000 #服务请求连接超时时间(毫秒)ReadTimeout: 3000 #服务请求处理超时时间(毫秒)OkToRetryOnAllOperations: true #对超时请求启用重试机制MaxAutoRetriesNextServer: 1 #切换重试实例的最大个数MaxAutoRetries: 1 # 切换实例后重试最大次数NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #修改负载均衡算法
-
局部配置
user-service:ribbon:ConnectTimeout: 1000 #服务请求连接超时时间(毫秒)ReadTimeout: 3000 #服务请求处理超时时间(毫秒)OkToRetryOnAllOperations: true #对超时请求启用重试机制MaxAutoRetriesNextServer: 1 #切换重试实例的最大个数MaxAutoRetries: 1 # 切换实例后重试最大次数NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #修改负载均衡算法
【源码地址】:GitHub