springcloud客户端负载均衡组件-RIBBON
RIBBON
介绍
ribbon是springcloud的框架中一个基础的负载均衡计算的客户端,实现微服务调用功能,代码中需要依赖RestTemplate对象,对他的api发送的http请求实现拦截,计算负载均衡,最终访问到具体的实例提供者获取功能的响应。
也属于netflix组件,和eureka一样,ribbon停更了,目前市面上没有更好的顶替措施,依然还在大面积的使用,功能强大,springcloud本来想要推出loadbalancer代替ribbon但是功能还是没有太完善,哪怕服务治理组件eureka替换成阿里巴巴nacos,也是支持ribbon的负载均衡
结构
任何一个具备ribbon组件的程序(web应用),都可以抓取注册信息之后,进行负载均衡的调用某个微服务的集群实例。
搭建一个微服务调用功能
引入ribbon组件和代码,然后负载均衡的调用hi-service的所有微服务提供者
pom文件
<dependencies><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></dependency></dependencies>
applicaotion.properties
server.port=8094
#配置一个当前ribbon调用工程的服务名称,但是这个工程web应用,该不该有服务名称
#该不该到注册中心注册,取决于需求,有没有人调用它.有调用者就注册,没有就不注册
#假设当前ribbon系统有接口被其他人调用的
spring.application.name=ribbon-service
server.servlet.context-path=/ribbon
#eureka.client.fetch-registry=false
#eureka.client.register-with-eureka=true
eureka.client.service-url.zone=http://localhost:8761/eureka
启动类
把启动类的当成一个配置类生成一个ribbon中使用的对象RestTemplate
@SpringBootApplicationpublicclassStarterRibbonBalance{publicstaticvoidmain(String[] args){SpringApplication.run(StarterRibbonBalance.class,args);}//ribbon需要给一个RestTemplate对象添加注解标识//把启动类看成一个配置类Configuration@Bean@LoadBalanced//标记作用,每次这个对象发送http请求,都要经过loadBalanced的拦截//只有加了这个注解,我们才能在代码中使用服务调用,否则必须是外网的域名或者ip//加了这个注解,反而不能使用baidu.com 10.9.9.9这种方法调用了,只能通过服务名称major-serivce//hi-serivcepublicRestTemplateinit(){returnnewRestTemplate();}//自定义负载均衡计算器 默认RoundRobinRule@BeanpublicIRuleruleInit(){//轮询,权重(基于响应时间的权重) 随机负载均衡returnnewRandomRule();//WeightedResponseTimeRule//RoundRobinRule}}
测试案例
提供访问8094的rubbon工程,实际上负载均衡独爱用service-hi的实例提供者。
开发测试代码
- helloService
@ServicepublicclassHelloService{@AutowiredprivateRestTemplate restTemplate;publicStringsayHi(String name){/*
想办法从业务代码发送http请求,到hi-service微服务中
*/return restTemplate.getForObject("http://hi-service/hello?name={1}",String.class,name);}}
- helloController.java
/**
* 负载均衡调用控制层
*/@RestControllerpublicclassHelloController{@AutowiredprivateHelloService helloService;/**
* 请求地址:/hello (由于当前项目context-path /ribbon/hello)
* 请求参数:name
* 返回数据:"RIBBON:"+负载均衡8091/8092/8093的字符串
* 例如本次负载均衡访问8091 最终从这个响应看到的
* RIBBON: hello eureka 王翠花,i am from 8091
*/@RequestMapping("/hello")publicStringsayHi(String name){return"RIBBON:"+helloService.sayHi(name);}}
结论1:在代码中,虽然请求url地址中,指向的是hi-service,但是最终访问的一定是某个后端实例的详细地址(localhost:8091/8092)
结论2:restTemplate如果能把hi-service替换成8091/8092,那么它在一定经过了拦截或者过滤编辑,负载均衡算法:轮询—其他算法
ribbon拦截原理
在ribbon的客户端中,配置的RestTemplate对象,有一个标识@LoadBalanced,一旦这个负载均衡,RestTemplate对象所有的http请求都要经过一个拦截器LoadBalancerInterceptor,是负载均衡计算的主要对象。
1.从请求中解析域名位置的字符串–hi-service
2.从eureka-client抓取的信息中(map.get(“hi-service”))拿到这个服务的所有实例
3.调用一个IRule计算规则(默认实现类RoundRobinRule轮询)从若干个节点中,计算负载均衡对应最终节点,拿到server对象(包含具体要访问的后端提供者)
4.拿到之后将请求路径中hi-service替换成该节点
http://hi-service/hello->http://localhost:8092/hello
5.请求发出,到达目的地
IRule接口和实现类
在springboot中的ribbon组件李,可以通过手动配置IRule实现类,替换负载均衡计算逻辑,默认是轮询
只要在容器中存在一个Irule类型的bean对象,就不在使用默认的轮询
//自定义负载均衡计算器 默认RoundRobinRule@BeanpublicIRuleruleInit(){//轮询,权重(基于响应时间的权重) 随机负载均衡returnnewRandomRule();//WeightedResponseTimeRule//RoundRobinRule