🌿Ribbon介绍
Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具,主要功能是提供客户端的软件负载均衡算法和服务调用。
如果使用的RestTemplate进行服务调用,那么创建RestTemplate的方法上面加@LoadBalanced注解就会开启Ribbon的负载均衡,Ribbon负载均衡有7种规则,默认轮询。
🍂Ribbon使用
创建子模块spring-cloud-ribbon(c服务)
添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<!--<version>2.2.1.RELEASE</version>-->
</dependency><dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
application.properties 创建c服务
server.port=8072 spring.application.name=nacos-c spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
Feign客户端调用a服务
@FeignClient(name="nacos-a")
public interface AServiceClient extends IUserService {
}
测试接口c服务调用a服务
@RestController
public class TestController {
@Autowired
private AServiceClient aServiceClient;
@GetMapping("/test")
public String callA(){
return aServiceClient.getName(100);
}
@GetMapping("/test2")
public String callA2(@RequestParam Integer time){
return aServiceClient.getSleep(time);
}
}
修改子模块user-api,然后打包package,安装install(目的放到本地仓库)
public interface IUserService {
//通过用户Id返回用户名称 /user/name?id=12
@GetMapping("/user/name")
String getName(@RequestParam Integer id);
//通过用户Id返回用户金额 /user/amount?id=12
@GetMapping("/user/amount")
Integer getAmount(@RequestParam Integer id);
//通过Id返回动态睡眠 /user/sleep?time=12
@GetMapping("/user/sleep")
String getSleep(@RequestParam Integer time);
}
修改子模块spring-cloud-nacos-a,然后打包package,运行jar包,并指定两个端口(8069/8070)
@RestController
public class UserServiceController implements IUserService {
@Value("${server.port}")
private String port;
@Override
public String getName(Integer id) {
return StrUtil.format("nacos a({}) 返回的id: {}" ,this.port,id);
}
@Override
public Integer getAmount(Integer id) {
return id*100;
}
@Override
public String getSleep(Integer time) {
//模拟time秒后读取数据资源
ThreadUtil.sleep(time*1000);
return StrUtil.format("nacos a({}) 睡眠了 {} 秒",this.port ,time);
}
}
开始访问c服务test接口,可以看到调用一次就换一个端口
轮询规则
🍁Ribbon负载均衡规则
Ribbon负载均衡有7种规则,默认轮询。
🌾修改负载均衡规则
建立自定义配置类
如下定义随机策略,那么调用一次就会随机换一个端口
@RestController
public class MyRuleConfig {
@Bean
public IRule rule(){
//定义随机策略
//return new RandomRule();
}
}
需要什么策略就new什么策略的,当然了除了这7种外我们也可以自定义策略
自定义规则类
修改权重
要想自定义规则,只需要继承AbstractLoadBalancerRule类即可,然后安装自定义的规则定义choose方法
public class MyRule extends AbstractLoadBalancerRule {
//注入Nacos提供的NacosDiscoveryProperties,来获取Nacos服务的属性(例如ip,权重等)
@Autowired
private NacosDiscoveryProperties nacosDiscoveryProperties;
//juc包下,线程安全的Integer
private static AtomicInteger count = new AtomicInteger(0);
@Override
//自动抛异常
@SneakyThrows
public Server choose(Object o) {
//获取负载均衡器
BaseLoadBalancer loadBalancer = (BaseLoadBalancer) this.getLoadBalancer();
//获取服务名
String serverName = loadBalancer.getName();
//命名服务实例
NamingService namingService = nacosDiscoveryProperties.namingServiceInstance();
//根据服务名获取所有服务实例,开启订阅
List<Instance> allInstances = namingService.getAllInstances(serverName, true);
//获取权重最大的实例
Instance maxInstance = allInstances.stream().max(Comparator.comparing(Instance::getWeight)).get();
//获取权重最小的实例
Instance minInstance = allInstances.stream().min(Comparator.comparing(Instance::getWeight)).get();
//初始化服务器
Server server = null;
//访问次数
int count2 = count.addAndGet(1);
//对访问次数取模
int mod = count2 % 5;
//余数为0时,选择端口为8069的服务器,否则选择8070服务器
if (mod == 0) {
//8069 权重3
server = new Server(minInstance.getIp(), minInstance.getPort());
} else {
//8070 权重9
server = new Server(maxInstance.getIp(), maxInstance.getPort());
}
return server;
}
@Override
public void initWithNiwsConfig(IClientConfig iClientConfig) {
}
}
配置类添加注解@RibbonClients
@RestController
//@RibbonClients(defaultConfiguration = MyRule.class) //全局服务设置负载规则
//@RibbonClient(name = "nacos-a",configuration = MyRule.class) //某个服务,设置负载规则
//默认轮询
public class MyRuleConfig {
@Bean
public IRule rule(){
//定义随机策略
//return new RandomRule();
//自定义策略:可以new,也可以用@RibbonClient注解
return new MyRule();
}
}
🍃设置超时时间
application.properties
#Ribbon相关配置 ##建立连接的超时时间 ribbon.ConnectionTimeout=5000 ##连接成功后,读取资源数据时的超时配置 ribbon.ReadTimeout = 3000
访问c服务test2接口,测试读取资源数据超时配置
可以看到超过配置时间,就会报错