摘要
Spring Cloud Netflix Ribbon 是Spring Cloud Netflix 子项目的核心组件之一,主要给服务间调用及API网关转发提供负载均衡的功能,本文将对其用法进行详细介绍。
Ribbon简介
在微服务架构中,很多服务都会部署多个,其他服务去调用该服务的时候,如何保证负载均衡是个不得不去考虑的问题。负载均衡可以增加系统的可用性和扩展性,当我们使用RestTemplate来调用其他服务时,Ribbon可以很方便的实现负载均衡功能。
LB负载均衡
LoadBalance ,请用户的请求平摊到多个服务上,从而达到系统的HA(高可用)。常见的负载均衡有软件Nginx、LVS、及硬件F5。
集中式LB
即在服务的消费者和提供者之间使用独立的LB设施,可以是硬件(F5)或是软件(Nignx、FVS),由该设施将访问请求按照某种策略转发至服务的提供方。Nignx常见的负载均衡策略就是轮询、iphash、设置权重。
进程内LB
将LB的逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后从中选择一个合适的服务器进行访问。
Ribbon就属于进程内负载均衡,他只是一个类库,集成于消费方进程,消费者通过它来获取到服务提供方的地址。
Ribbon本地负载均衡客户端 VS Nignx服务端负载均衡区别
- Nginx是服务器负载均衡,客户端所有请求都会交给Nginx,然后由nginx实现转发请求。即负载均衡是由服务器端实现的。
- Ribbon本地负载均衡,在调用微服务接口时,会在注册中心上获取注册信息列表之后缓存到JVM本地,从而在本地实现RPC远程调用。
Ribbon负载均衡架构图
RestTemplate的使用
RestTemplate是一个HTTP客户端,使用它我们可以方便的调用HTTP接口,支持GET、POST、PUT、DELETE等方法。
GET请求方法
getForObject方法
返回对象为响应体中数据转化成的对象,举例如下:
@GetMapping(value = "/consumer/nacos/payment/{id}")
public String getOrder(@PathVariable("id") String id){
return restTemplate.getForObject(serverURL+"/payment/nacos/"+id,String.class);
}
getForEntity方法
返回对象为ResponseEntity对象,包含了响应中的一些重要信息,比如响应头、响应状态码、响应体等,举例如下:
@GetMapping(value = "/consumer/nacos/payment/{id}")
public String getOrder(@PathVariable("id") String id){
ResponseEntity<String> entity = restTemplate.getForEntity(serverURL + "/payment/nacos/" + id, String.class);
HttpHeaders headers = entity.getHeaders();
System.out.println(headers);
System.out.println(entity.getBody());
return restTemplate.getForObject(serverURL+"/payment/nacos/"+id,String.class);
}
响应头信息:[Content-Type:"text/plain;charset=UTF-8", Content-Length:"37", Date:"Sat, 24 Oct 2020 12:52:40 GMT", Keep-Alive:"timeout=60", Connection:"keep-alive"]
响应体:nacos registry, serverPort: 9001 id1
POST请求方法
postForObject示例
@PostMapping("/insert")
public Result insert(@RequestBody User user) {
return restTemplate.postForObject(userServiceUrl + "/user/insert", user, Result.class);
}
postForEntity示例
@PostMapping("/insert")
public Result insert(@RequestBody User user) {
return restTemplate.postForEntity(userServiceUrl + "/user/insert", user, Result.class).getBody();
}
Ribbon的常用配置
全局配置
ribbon:
ConnectTimeout: 1000 #服务请求连接超时时间(毫秒)
ReadTimeout: 3000 #服务请求处理超时时间(毫秒)
OkToRetryOnAllOperations: true #对超时请求启用重试机制
MaxAutoRetriesNextServer: 1 #切换重试实例的最大个数
MaxAutoRetries: 1 # 切换实例后重试最大次数
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #修改负载均衡算
指定服务进行配置
与全局配置的区别就是ribbon节点挂在服务名称下面。
Ribbon的负载均衡策略
所谓的负载均衡策略,就是当A服务调用B服务时,此时B服务有多个实例,这时A服务以何种方式来选择调用的B实例,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:采用双重过滤,同时过滤不是同一区域的实例和故障实例,选择并发较小的实例。