引言
说完了注册中心Eureka,虽然Eureka可以实现服务的发现和调用,但在微服务体系中,服务的发现和调用往往是需要伴随着负载均衡这个概念一体的。而在SpringCloud中自然也存在着与Eureka配套的负载均衡组件,也就是Ribbon组件。
Ribbon介绍
Spring Cloud Ribbon是基于Netflix Ribbon实现的一套 客户端 负载均衡 工具
简单的说,Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说,就是在配置文件中列出Load Balancer(简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这次额机器。我们也很容易使用Ribbon实现自定义的负载均衡算法。
使用 Ribbon 工作原理
所有的项目都会注册到 Eureka 中,Eureka 允许不同项目的 spring.application.name 相同。当相同时会认为是这些项目是一个集群,所以同一个项目部署多次都是设置应用程序名相同。
Application Client 会从 Eureka 中根据 spring.application.name 加载 Application Service 的列表。根据设定的负载均衡算法,从列表中取出一个 URL,到此 Ribbon 的事情结束。剩下的事情由程序员自己进行技术选型,选择一个 HTTP 协议工具,通过这个 URL 调用 Application Service。
注意:以下事情和 Ribbon 没有关系的
Application Service 注册到 Eureka 过程。这是 Eureka 的功能。
Application Client 从 Eureka 取出注册列表。这是 Eureka 的功能。
Application Client 通过 URL 访问 Application Service 。这个根据自己使用的 HTTP 工具。
只有 Application Client 从 Eureka 中取出列表后进行负载均衡算法的过程和Ribbon有关。
Ribbon使用
- 1.导入依赖,需要在消费者中导入ribbon和eureka依赖
<!--Ribbon--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-ribbon</artifactId></dependency><!--Eureka--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-eureka</artifactId><version>1.4.6.RELEASE</version></dependency>
- 2.配置文件
#Eureka
eureka:
client:
register-with-eureka: false #不在注册中心注册自己
service-url:
defaultZone : http://eureka8001.com:8001/eureka/,http://eureka8002.com:8002/eureka/,http://eureka8003.com:8003/eureka/
- 3.添加负载均衡注解
@ConfigurationpublicclassBeanConfig{@Bean@LoadBalanced//Ribbon开启负载均衡publicRestTemplategetRestTemplate(){returnnewRestTemplate();}}
- 4.启动类添加Eureka注解
配置多个服务提供者
为了明确的表示,注册中心和负载均衡的功能实现,启动三个Eureka服务,启动三个服务提供者,启动一个服务消费者,目标实现==调用服务消费者相同的接口,调用不同的服务提供者的服务。==不同的服务返回不同的id:7001,7002,7003
项目启动后,每一个eureka中有两个eureka服务,相同的application有对应三个服务提供者
访问相同的服务地址,负载均衡到不同的服务提供者,不影响返回的结果。(id为了区分不同的服务而设置)
Ribbon核心组件IRule实现负载均衡算法
IRule:根据特定算法从服务列表中选取一个要访问的服务。默认是轮询
每一接口实现,都是一个负载均衡策略
设置随机的负载均衡策略
在配置类中,生成一个有spring管理的IRule对象,当项目启动后如果有spring管理的bean,则用相应的负载均衡策略,如果没有,则使用默认的随机策略。
@ConfigurationpublicclassBeanConfig{@Bean@LoadBalanced//Ribbon开启负载君和的注解//AvailabilityFilteringRule 过滤掉跳闸,加载慢。。的服务,其他的轮询//RandomRule 随机//RetryRule 重试//RoundRobinRule 轮询//WeightedResponseTimeRule 设置权重publicRestTemplategetRestTemplate(){returnnewRestTemplate();}//设置随机的负载均衡策略@BeanpublicIRulemyRule(){returnnewRandomRule();}}
自定义负载均衡策略(依次访问3次,循环访问)
- .模仿实现类
- 具体代码实现
packagecom.kuang.myRule;importcom.netflix.client.config.IClientConfig;importcom.netflix.loadbalancer.AbstractLoadBalancerRule;importcom.netflix.loadbalancer.ILoadBalancer;importcom.netflix.loadbalancer.Server;importjava.util.List;importjava.util.concurrent.ThreadLocalRandom;publicclass myRule extendsAbstractLoadBalancerRule{privateint total =0;privateint currentIndex =0;publicServerchoose(ILoadBalancer lb,Object key){if(lb ==null){returnnull;}else{Server server =null;while(server ==null){if(Thread.interrupted()){returnnull;}List<Server> upList = lb.getReachableServers();List<Server> allList = lb.getAllServers();int serverCount = allList.size();if(serverCount ==0){returnnull;}//自定义部分代码开始if(total<3){
server =upList.get(currentIndex);
total++;}else{
total=1;
currentIndex++;if(currentIndex>allList.size()-1){//如果有服务挂起,不会报错
currentIndex=0;}}
server =upList.get(currentIndex);//自定义部分代码结束//原随机代码//int index = this.chooseRandomInt(serverCount); 获取随机下标// server = (Server)upList.get(index); 获取serverif(server ==null){Thread.yield();}else{if(server.isAlive()){return server;}
server =null;Thread.yield();}}return server;}}protectedintchooseRandomInt(int serverCount){returnThreadLocalRandom.current().nextInt(serverCount);}publicServerchoose(Object key){returnthis.choose(this.getLoadBalancer(), key);}publicvoidinitWithNiwsConfig(IClientConfig clientConfig){}}
- 将配置类中的负载均衡换成自定义 这样就可以实现没有服务轮询三次的负载均衡策略。
版权归原作者 桥边大爷 所有, 如有侵权,请联系我们删除。