Ribbon
是一个客户端负载均衡工具,主要功能是将面向服务的Rest模板(RestTemplate)请求转换成客户端负载均衡的服务调用。通过Ribbon,开发人员可以在客户端实现请求的负载均衡,而无需单独部署负载均衡器。Ribbon支持多种负载均衡算法,如轮询、随机
、加权等,只需要在配置文件类中添加@LoadBalanced
。
Ribbon配置在消费者模块中
之前写过消费者的模块 =>SpringCloud之消费者
本文章的目的是:利用Ribbon实现负载均衡
1、导入依赖
<!-- ribbon & eureka --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-ribbon</artifactId><version>1.4.6.RELEASE</version></dependency>
2、创建配置文件类
只需要在RestTemplate上添加
@LoadBalanced
注解
@Configuration
public class ConfigBean {/*** http请求* @return*/@Bean@LoadBalanced // 使用Ribbonpublic RestTemplate getRestTemplate(){return new RestTemplate();}@Beanpublic IRule getRule(){return new RandomRule(); // 随机
// return new MyRule(); 自定义}}
3、定义负载均衡的规则
实现了IRule的实现类如下:
具体实现类作用如下:
RandomRule:随机规则。使用Random对象从服务列表中随机选择一个服务实例。这种规则在每次请求时都会随机选择一个服务实例,有助于实现请求的均匀分布。RoundRobinRule:轮询规则。这是Ribbon的默认规则,也是更高级规则的回退策略。它按照顺序依次选择服务实例进行调用,实现了一种简单的负载均衡。RetryRule:重试规则。这种规则首先使用RoundRobinRule进行服务实例选择,如果选择服务实例失败或在指定时间内没有响应,则会在一定时间内不断进行重试,直到找到可用的服务实例或超时。WeightedResponseTimeRule:加权响应时间规则。这种规则会根据每个服务实例的平均响应时间计算权重,响应时间越快的服务实例权重越高,被选中的概率也越高。这种规则能够优先将请求分发给性能更好的服务实例。BestAvailableRule:最佳可用规则。它会选择并发量最小的服务实例进行调用,有助于平衡各个服务实例的负载。ZoneAvoidanceRule:区域感知规则。在非AWS环境下,可以将其理解为根据机房或Eureka集群来选择服务实例。它会优先选择同区域的服务实例,当同区域的服务实例不可用时,才会选择其他区域的服务实例。
4、自定义负载均衡的规则
自定义负载均衡需要注意的是自己创建的MyRule类不能和项目启动器类放在同一个文件夹内,即不能被Spring Boot扫描到。所以需要放置在启动类所在的包之外的独立包中。
/*** 注意 这个类不能被主启动类扫描 所以需要放在com.jyl下的目录*/
@Configuration
public class MyRule extends AbstractLoadBalancerRule {/*** 实现一个每个服务只能访问5次,访问五次后换下一个服务* @param lb* @param key* @return*/private int total = 0 ;// 被调用的次数private int currentIndex = 0 ; // 当前被调用的服务public MyRule(){}// @SuppressWarnings({"RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE"})public Server choose(ILoadBalancer lb, Object key) {if (lb == null) {return null;} else {Server server = null;while(server == null) {if (Thread.interrupted()) {return null;}// 获得活着的服务List<Server> upList = lb.getReachableServers();// 获得全部的服务List<Server> allList = lb.getAllServers();int serverCount = allList.size();if (serverCount == 0) {return null;}
// // 生成区间随机数
// int index = this.chooseRandomInt(serverCount);
// // 随机获取一个
// server = (Server)upList.get(index);if(total < 5){server = upList.get(currentIndex);total++;}else {total = 0 ;currentIndex++ ; // 5 + 1if (currentIndex > upList.size()){currentIndex = 0 ;}// 从活着的服务中, 获取指定的服务来进行操作server = upList.get(currentIndex);}if (server == null) {Thread.yield();} else {if (server.isAlive()) {return server;}server = null;Thread.yield();}}return server;}}protected int chooseRandomInt(int serverCount) {return ThreadLocalRandom.current().nextInt(serverCount);}public Server choose(Object key) {return this.choose(this.getLoadBalancer(), key);}public void initWithNiwsConfig(IClientConfig clientConfig) {}
}
5、启动器类
需要添加@RibbonClient注解
需要的参数是name
=“Eureka界面中的Application提供者的名称” 和configuration
=自定义类
@SpringBootApplication
@EnableEurekaClient
//再微服务启动的时候就可以加载自定义ribbon类
@RibbonClient(name = "SPRINGCLOUD-PROVIDER-DEPT",configuration = MyRule.class)
public class DeptConsumer_80 {public static void main(String[] args) {SpringApplication.run(DeptConsumer_80.class,args);}
}
6、创建数据库&提供者模块
到这里还没有结束
,需要体验到负载均衡的效果,需要使用三个提供者,三个提供者要使用不同的数据库
之前有写过提供者的案例=>这里!!!
创建数据库名db01、db02、db03,创建相同的dept表如下:
CREATE TABLE `dept` (`deptno` bigint(20) NOT NULL AUTO_INCREMENT,`dname` varchar(50) DEFAULT NULL,`db_source` varchar(50) DEFAULT NULL,PRIMARY KEY (`deptno`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;
只需要修改配置文件中的数据库名提供者依次连接数据库,如:提供者1连接db01
# spring 的配置spring:application:name: springcloud-provider-deptdatasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: org.gjt.mm.mysql.Driverurl: jdbc:mysql://localhost:3306/数据库名?useUnicode=true&useSSL=false&characterEncoding=utf-8username: rootpassword: root
7、启动eureka&提供者
启动3个eureka服务、3个提供者和一个消费者
随机访问一个eureka服务界面
比如访问:http://localhost:7001/
说明3个提供者已经注册到了eureka集群中了
8、测试负载均衡
默认的负载均衡策略是轮询
如果需要修改负载均衡策略可以再配置文件类中设置
@Configuration
public class ConfigBean {@Beanpublic IRule getRule(){return new RandomRule(); // 随机
// return new MyRule(); 自定义}
}
【每日自勉+1】“业精于勤,荒于嬉;行成于思,毁于随。”——韩愈。