Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。
简单的说,Ribbon是Netflix发布的开源项目, 主要功能是提供客户端的软件负载均衡算法,将NetFlix的中间层服务连接在一起。 Ribbon的客户端组件提供一系列完整的配置项如:连接超时、重试等等。简单的说,就是在配置文件中列出LoadBalancer (简称LB: 负载均衡)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等等)去连接这些机器。我们也很容易使用Ribbon实现自定义的负载均衡算法!
LB,即负载均衡(Load Balance) ,在微服务或分布式集群中经常用的一种应用。
负载均衡简单的说就是将用户的请求平摊的分配到多个服务上,从而达到系统的HA (高可用) .
常见的负载均衡软件有 Nginx,Lvs等等
dubbo、SpringCloud中均给我们提供了负载均衡,SpringCloud的负载均衡算法可以自定义
集中式LB
即在服务的消费方和提供方之间使用独立的LB设施,如Nginx, 由该设施负责把访问请求通过某种策略转发至服务的提供方!
进程式LB
将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选出一个合适的服务器。
Ribbon就属于进程内LB,它只是一个类库,集成于消费方进程,消费方通过它来获取到服务提供方的地址!
在消费者 配置Eureka和Ribbon负载均衡依赖
pom.xml
org.springframework.cloud
spring-cloud-starter-eureka
1.4.6.RELEASE
org.springframework.cloud
spring-cloud-starter-ribbon
1.4.6.RELEASE
修改application.yml配置
server:
port: 8004
eureka:
client:
register-with-eureka: false #不向Eureka中注册自己
service-url:
defaultZone: http://localhost:8005/eureka/
在配置类的RestTemplate方法加上注解@LoadBalanced实现ribbon的负载均衡
@Configuration
public class ConfigBean {
@Bean
@LoadBalanced //配置负载均衡实现RestTemplate
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
配置完成后,我们就可以通过服务名来访问其他服务。把提供者的地址,改成服务名后,启动代码访问接口
private static final String REST_URL_PERFIX = "http://SPRINGCLOUD-PROVIDER-DEPT";
当前提供方只有一个项目,当前体会不到负载均衡,所以需要创建多个提供方来实现负载均衡
再创建两个提供者以及两个数据库,新建的提供者的结构与第一个提供者的相同
添加依赖,与第一个提供者的依赖相同
新建两个提供者的application.yml如下(只是端口号不同即可)
server:
port: 8006
mybatis:
type-aliases-package: com.zlt.springcloud.pojo
mapper-locations: classpath:mapper/*.xml
spring:
application:
name: springcloud-provider-dept
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/db01?
username: root
password: 123456
hikari:
pool-name: DateHikariCP
# ???????
minimum-idle: 5
# ???????,??600000(10??)
idle-timeout: 1800000
# ????????10
maximum-pool-size: 10
# ?????????????
auto-commit: true
# ?????????0???????1800000?30???
max-lifetime: 18000000
# ?????????30000?30??
connection-timeout: 30000
eureka:
client:
service-url:
defaultZone: http://localhost:8005/eureka/
instance:
instance-id: springcloud-provider-8006 #修改eureak上默认描述的信息
info:
app.name: springcloud02
company.name: hahaha
添加完成后。启动服务端、三个提供者、以及消费者。
在eureka注册中心可以看到,一个服务中有三个实例
localhost:8004/consumer/dept/list 访问,多次刷新,我们这次可以直观的看到显示不同服务的数据,这次我们可直观的感受到负载均衡的应用。 这是ribbon默认的算法,通过轮询访问实例。
如何使用其他模式呢?
在消费者的配置类里面进行配置,配置一个IRule类,里面返回需要的模式就好了,比如这里是随机模式
@Configuration
public class ConfigBean {
@Bean
@LoadBalanced //配置负载均衡实现RestTemplate
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
@Bean
public IRule myRule(){
return new RandomRule();
}
}
启动服务器、提供者、消费者,然后访问3次http://localhost:8004//consumer/getlist
发现访问三个实例的顺序是随机的
在主目录外 创建myrule文件包
在myrule下创建MyRule配置类
在myrule包下创建DiyRandomRule,双击shift搜索 RandomRule 全部复制,改为自己自定义算法负载均衡
public class DiyRandomRule extends AbstractLoadBalancerRule {
//代码全是复制的 DiyRandomRule.class的,自定义负载均衡需要自己修改
//当前自定义负载均衡:
//每个服务访问5次。换下一个服务
//total=0,默认=0,如果=5,指向下一个服务节点
//index=0,默认0,如果total=5,则inedx+1
private int totla=0;//被调用的次数
private int currentIndex=0;//当前是谁在提供服务
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 upList = lb.getReachableServers();//获得活着的服务
List allList = lb.getAllServers();//获得全部的服务
int serverCount = allList.size();
if (serverCount == 0) {
return null;
}
//int index = this.chooseRandomInt(serverCount);//生成区间随机数
//server = (Server) upList.get(index);//从活着的服务中,随机获取一个
//================自定义负载均衡算法==================
if(totla<5){
server = upList.get(currentIndex);
totla++;
}else{
totla=0;
currentIndex++;
if (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) {
}
}
在消费者启动器上添加自定义负载均衡配置引用的@RibbonClien注解
@SpringBootApplication
@EnableEurekaClient
@RibbonClient(name = "SPRINGCLOUD-PROVIDER-DEPT",configuration = MyRule.class)
public class DeptConsumer_80 {
public static void main(String[] args) {
SpringApplication.run(DeptConsumer_80.class,args);
}
}
重启服务, 访问多次http://localhost:8004//consumer/getlist
我们可看到页面每刷新五次值会更改