Ribbon介绍
Ribbon是Netflix公司开源的一个负载均衡的项目(https://github.com/Netflix/ribbon),它是一个基于HTTP、TCP的客户端负载均衡器。
什么是负载均衡?
负载均衡是微服务架构中必须使用的技术,通过负载均衡来实现系统的高可用、集群扩容等功能。负载均衡可通过硬件设备及软件来实现,硬件比如:F5、Array等,软件比如:Nginx等。
如下图是负载均衡的架构图:
用户请求先到达负载均衡器(也相当于一个服务)或者均衡器集群,负载均衡器根据负载均衡算法将请求转发到微服务。负载均衡算法有:轮训、随机、加权轮训、加权随机、地址哈希等方法,负载均衡器维护一份服务列表,根据负载均衡算法将请求转发到相应的微服务上,所以负载均衡可以为微服务集群分担请求,降低系统的压力。
什么是客户端负载均衡?
上图是服务端负载均衡,客户端负载均衡与服务端负载均衡的区别在于客户端要维护一份服务列表,Ribbon从Eureka Server获取服务列表,Ribbon根据负载均衡算法直接请求到具体的微服务,中间省去了负载均衡服务。如下图是在网上找的Ribbon负载均衡的流程图:
1、在消费微服务中使用Ribbon实现负载均衡,Ribbon先从EurekaServer中获取服务列表。
2、Ribbon根据负载均衡的算法去调用微服务。
在Eureka client 中使用Ribbon
Spring Cloud引入Ribbon配合 restTemplate 实现客户端负载均衡。Java中远程调用的技术有很多,如webservice、socket、rmi、Apache HttpClient、OkHttp等,互联网项目使用基于http的客户端较多,本项目使用OkHttp。
导入ribbon所需的依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
<version>1.3.6.RELEASE</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
</dependency>
在application.yml中配置ribbon相关配置
ribbon:
MaxAutoRetries: 2 #最大重试次数,当Eureka中可以找到服务,但是服务连不上时将会重试
MaxAutoRetriesNextServer: 3 #切换实例的重试次数
OkToRetryOnAllOperations: false #对所有操作请求都进行重试,如果是get则可以,如果是post,put等操作没有实现幂等的情况下是很危险的,所以设置为false
ConnectTimeout: 5000 #请求连接的超时时间ReadTimeout: 6000 #请求处理的超时时间
负载均衡测试
1)启动生产者微服务..看看是否在Eureka Server中注册成功
2)定义RestTemplate,使用@LoadBalanced注解
在消费者的启动类中定义RestTemplate,让ribbon 切入,根据restTemplate 提供的serverId 找到对应的服务,并调用
@Bean //配置一个resttemplate 远程调用类
@LoadBalanced //配置切面注解,使
public RestTemplate restTemplate(){
return new RestTemplate(new OkHttp3ClientHttpRequestFactory());
}
测试调用
服务id 是根据Eureka Server中定的
请求地址 是生产者提供的调用路径 也就是 /get/id
@SpringBootTest
@RunWith(SpringRunner.class)
public class RibbonTest {
@Resource
RestTemplate restTemplate;
@Test
public void fun01(){
// 服务id
String serverId = "XC-SERVER-CMS";
// 通过服务id 调用
ResponseEntity<Map> responseEntity = restTemplate.getForEntity("http://" + serverId + "/get/5a754adf6abb500ad05688d9", Map.class);
Map body = responseEntity.getBody();
System.out.println(body);
}
}
测试结果 body是查询到数据了的,也就是服务调用成功
可能有人会觉得很麻烦,因为每次都需要拼装数据,Feign 很好的解决了这个问题,使复杂的调用过程变成调用接口从而轻易实现远程调用