✨✨个人主页:沫洺的主页
📚📚系列专栏: 📖 JavaWeb专栏📖 JavaSE专栏 📖 Java基础专栏📖vue3专栏
📖MyBatis专栏📖Spring专栏📖SpringMVC专栏📖SpringBoot专栏
📖Docker专栏📖Reids专栏📖MQ专栏📖SpringCloud专栏
💖💖如果文章对你有所帮助请留下三连✨✨
衔接上篇: [Spring Cloud] nacos作为服务中心_沫洺的博客-CSDN博客
🌿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负载均衡规则
Ribbon负载均衡有7种规则,默认轮询。
参考文章: Spring Cloud 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接口,测试读取资源数据超时配置
可以看到超过配置时间,就会报错