1、简述
Spring Cloud Ribbon是一个基于http和tcp的客户端负载均衡器,是基于Netflix Ribbon实现的。在微服务架构中,业务都会被拆分成一个独立的服务,服务与服务的通讯是基于http Restful的。
Spring Cloud有两种服务调用方式,一种是ribbon+restTemplate,另一种是feign。
Ribbon是一个服务调用组件,并且是一个客户端实现负载均衡的处理的组件。
2、负载均衡
服务端负载均衡常用通过Nginx来实现:
客户端负载均衡通过Ribbon来实现:
备注:以上图有问题,Eureka Server IP 分别为192.168.220.141,192.168.220.142,192.168.220.143
3、Ribbon 负载均衡策略
Ribbon 的负载均衡策略是由 IRule 接口定义, 该接口由如下实现:
要使用Ribbon 实现负载均衡,在Spring的配置类中添加负载均衡接口
负载均衡的接口:ILoadBalancer接口
切换负载均衡策略:
@Bean
public IRule iRule(){
return new RoundRobinRule();
}
负载均衡实现 | 策略概述 |
---|---|
RandomRule | 随机 |
RoundRobinRule | 轮询 |
AvailabilityFilteringRule | 先过滤掉由于多次访问故障的服务,以及并 发连接数超过阈值的服务,然后对剩下的服 务按照轮询策略进行访问; |
WeightedResponseTimeRule | 根据平均响应时间计算所有服务的权重,响 应时间越快服务权重就越大被选中的概率即 越高,如果服务刚启动时统计信息不足,则 使用RoundRobinRule策略,待统计信息足够会切换到WeightedResponseTimeRule策略 |
RetryRule | 先按照RoundRobinRule策略分发,如果分发 到的服务不能访问,则在指定时间内进行重试,然后分发其他可用的服务 |
BestAvailableRule | 先过滤掉由于多次访问故障的服务,然后选择一个并发量最小的服务; |
ZoneAvoidanceRule | 综合判断服务节点所在区域的性能和服务节点的可用性,来决定选择哪个服务 |
备注:如果没有指定负载均衡策略,ribbon默认的负载均衡是ZoneAvoidanceRule。
4、Ribbon配置
因Ribbon的依赖已经集成在Eureka上,顾无需再引用Ribbon的依赖。只要配置当前RestTemplate 初始化和负载均衡策略即可。
package com.lm.shop.order.config;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RoundRobinRule;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
* @author lsk
* @version 1.0.0
* @ClassName MyRibbonConfig.java
* @Description ribbon 配置
* @createTime 2022年10月24日 16:35:00
*/
@Configuration
public class MyRibbonConfig {
/**
* @title restTemplate
* @description 使用ribbon负载均衡
* @author lsk
* @updateTime 2022/10/24 16:42
* @return: org.springframework.web.client.RestTemplate
* @throws
*/
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
/**
* @title iRule
* @description 配置负载均衡策略
* @author lsk
* @updateTime 2022/10/24 16:39
* @return: com.netflix.loadbalancer.IRule
* @throws
*/
@Bean
public IRule iRule(){
return new RoundRobinRule();
}
}
5、RestTemplate 服务的调用
通过RestTemplate 调用Eureka注册的服务名称,调用对应的接口即可。客户端会根据定义的负载均衡策略调用服务接口。
package com.lm.shop.order.controller;
import com.lm.shop.common.utils.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.util.List;
/**
* @author lsk
* @version 1.0.0
* @ClassName OrderController.java
* @Description 订单控制层
* @createTime 2022年10月19日 19:17:00
*/
@RestController
@RequestMapping("sku")
public class SkuController {
@Autowired
private RestTemplate restTemplate;
private static final String PRODUCT_SERVER = "http://SHOP-PRODUCT/";
@GetMapping("/getProduct")
public R getProduct(){
ResponseEntity<R> responseEntity = restTemplate.getForEntity(PRODUCT_SERVER + "/product/getProductById?id=1",R.class);
return R.ok().setData(responseEntity.getBody());
}
}
6、自定义负载均衡策略
对IRule实现,添加自己的负载均衡规则。
package com.lm.shop.order.rule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.Server;
import java.util.List;
/**
* @author lsk
* @version 1.0.0
* @ClassName MyRule.java
* @Description 自定义负载均衡
* @createTime 2022年10月25日 14:10:00
*/
public class MyRule implements IRule {
private ILoadBalancer iLoadBalancer;
@Override
public Server choose(Object o) {
final List<Server> allServers = this.iLoadBalancer.getAllServers();
int index = (int)(+Math.random()*(allServers.size() -1));
return allServers.get(index);
}
@Override
public void setLoadBalancer(ILoadBalancer iLoadBalancer) {
iLoadBalancer = iLoadBalancer;
}
@Override
public ILoadBalancer getLoadBalancer() {
return iLoadBalancer;
}
}
在MyRibbonConfig类中初始化配置中调整自己的负载均衡策略:
@Bean
public IRule iRule(){
// return new RoundRobinRule();
return new MyRule();
}
7、Ribbon加载模式
Ribbon默认是懒加载微服务,首次加载特别慢,我们可以在application.properties修改为饥饿加载。
#默认的懒加载微服务,首次启动慢,改成true为饥饿加载
ribbon.eager-load.enabled=false
8、结语
Ribbon是构建高可用的微服务架构的重要工具,通过其强大的客户端负载均衡功能,可以保证微服务之间的通信始终可靠。如果你正在构建一个微服务架构,不妨考虑使用Ribbon来提升系统的稳定性和可靠性。
项目Gitee:https://gitee.com/lhdxhl/lhdx-shop.git
评论区