SpringCloud实战-Ribbon客户端负载均衡
前面我们已经完成了注册中心和服务提供者两个基础组件。接着介绍使用Spring Cloud Ribbon在客户端负载均衡的调用服务。
ribbon 是一个客户端负载均衡器,可以简单的理解成类似于 nginx的负载均衡模块的功能。
主流的LB方案可分成两类:
一种是集中式LB, 即在服务的消费方和提供方之间使用独立的LB设施(可以是硬件,如F5, 也可以是软件,如nginx), 由该设施负责把访问请求通过某种策略转发至服务的提供方;
另一种是进程内LB,将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的服务器。Ribbon就属于后者,它只是一个类库,集成于消费方进程,消费方通过它来获取到服务提供方的地址。
Ribbon的架构图:如下:

1.首先我们先在原来的基础上新建一个Ribbon模块,如下图:

现在我们单独使用ribbon,在Ribbon模块下添加依赖,如下图所示:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
<version>1.4.0.RELEASE</version>
</dependency>
修改application.yml文件,如下所示:
server:
port: 8082
spring:
application:
name: Ribbon-Consumer
#providers这个是自己命名的,ribbon,listOfServer这两个是规定的
providers:
ribbon:
listOfServers: localhost:8080,localhost:8081
在Ribbon模块下新建一个测试类如下代码 * Created by cong on 2018/5/8. */
@RestController
public class ConsumerController {
//注入负载均衡客户端
@Autowired
private LoadBalancerClient loadBalancerClient; @RequestMapping("/consumer")
public String helloConsumer() throws ExecutionException, InterruptedException {
//这里是根据配置文件的那个providers属性取的
ServiceInstance serviceInstance = loadBalancerClient.choose("providers");
//负载均衡算法默认是轮询,轮询取得服务
URI uri = URI.create(String.format("http://%s:%s", serviceInstance.getHost(), serviceInstance.getPort()));
return uri.toString();
}
运行结果如下:
会轮询的获取到两个服务的URL 访问第一次,浏览器出现http://localhost:8080 访问第二次就会出现http://localhost:8081

在这里给普及一下有哪些负载均衡算法:
1:简单轮询负载均衡(RoundRobin)
以轮询的方式依次将请求调度不同的服务器,即每次调度执行i = (i + 1) mod n,并选出第i台服务器。
2:随机负载均衡 (Random)
随机选择状态为UP的Server
3:加权响应时间负载均衡 (WeightedResponseTime)
根据相应时间分配一个weight,相应时间越长,weight越小,被选中的可能性越低。
4:区域感知轮询负载均衡(ZoneAvoidanceRule)
复合判断server所在区域的性能和server的可用性选择server


有兴趣的还可以看一下我在Ngnix的随笔文章中列出的负载均衡算法实现:http://www.cnblogs.com/huangjuncong/p/8319182.html
如果想配置其他轮询算法在yml配置文件中配置,如下配置一个随机算法所示:
server:
port: 8082
spring:
application:
name: Ribbon-Consumer
#providers这个是自己命名的,ribbon,listOfServer这两个是规定的
providers:
ribbon:
listOfServers: localhost:8080,localhost:8081 ##如果不想选用默认的轮询的负载均衡算法,在这里做如下配置
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
接着在启动类动一下手脚让我们配置的随机算法的负载均衡生效,只需要实现一个实现了IRule接口的Bean即可,如下:
package hjc; import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate; @SpringBootApplication
public class RibbonApplication { public static void main(String[] args) {
SpringApplication.run(RibbonApplication.class, args);
} @Bean
public IRule ribbonRule(){
return new RandomRule();
}
}
因此重新启动Ribbon启动类,得到的结果是随机的,如下所示:
浏览器随机出现http://localhost:8080 或者http://localhost:8081
那么问题来了,服务的地址是写死在配置文件中,如果某个服务挂了,那么还会把请求转发到挂掉的服务中,因此,解决的办法是,跟Eureka对接,结合一起用。就可以依靠Eureka动态的获取一个可用的服务列表,隔一段时间我就更新一次,
或者Eureka设置一个监听端口,某一个服务挂了,Eureka通知我,我会知道,变更服务列表,这样不久形成一个闭环了吗?这样就不存在高可用性问题了。跟Eureka配合一起用同时解决了的Ribbon的单点故障问题。
第一步,毫无疑问就是修改Ribbon模块的pom.xml文件,加入如下依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.3.5.RELEASE</version>
</dependency>
第二步,修改yml配置文件如下:
server:
port:
spring:
application:
name: Ribbon-Consumer eureka:
#客户端
client:
#注册中心地址
service-url:
defaultZone: http://localhost:8888/eureka/,http://localhost:8889/eureka/
这样就可以跟Eureka结合,这样Ribbon就可以通过Eureka动态的获取服务列表
接着在启动类加上服务发现注解,如下:
@EnableDiscoveryClient
启动类接着声明一个负载均衡的请求器@LoadBalanced,还有请求发起的工具RestTemplate
如下代码:
@SpringBootApplication
@EnableDiscoveryClient
public class RibbonApplication { public static void main(String[] args) {
SpringApplication.run(RibbonApplication.class, args);
} @Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
} }
接着我们在上一节文章中的两个provider1,provider2模块添加一下测试代码:如下:
provider1:
package hjc.hello; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; /**
* Created by cong on 2018/5/8.
*/
@RestController
public class HelloController { @RequestMapping("/hello")
public String hello(){
return "hello1";
} }
provider2代码如下:
package hjc.hello; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; /**
* Created by cong on 2018/5/8.
*/
@RestController
public class HelloController { @RequestMapping("/hello")
public String hello(){
return "hello2";
} }
接着我们用RestTemplate进行面向服务调用,不再面向IP调用。
如下代码:
/**
* Created by cong on 2018/5/8.
*/
@RestController
public class ConsumerController { @Autowired
private RestTemplate restTemplate; @RequestMapping("/consumer")
public String helloConsumer() throws ExecutionException, InterruptedException { return restTemplate.getForEntity("http://HELLO-SERVICE/hello",String.class).getBody(); }
接着启动Ribbon模块,我们看一下Eureka仪表盘,如下:

可以看到多了RIBBON-CONSUMER服务
接着我们继续在已经运行的Ribbon模块上,在浏览器输入localhost:8082,运行结果如下:
hello1或者hello2,
可以看到hello1 ,hello2轮询方式出现,因为默认就是轮询方式
到这里我们还发现Ribbon还是单点故障的,这里我来解释一下:
因为这里我是单独建立一个SpringBoot的Ribbon模块,实际使用并不是这样用的,Ribbon是客户端的负载均衡,是跟客户端绑定在一起的,我们实际运用的时候往往会在服务里面引入一个客户端负载均衡去连接到Eureka客户中心,
这样我们还存在Ribbon单点故障吗?不存在了,因为我们服务提供者就是高可用的,这样还是个单点吗?这里读者的思考必须转过弯来,这一篇随笔我只是为了演示Ribbon,实际使用并不是这样用的。
SpringCloud实战-Ribbon客户端负载均衡的更多相关文章
- springcloud 之Ribbon客户端负载均衡配置使用
pom.xml添加配置说明:这里服务注册与发现用的是Eureka,所以消费者端需要引入eureka,使用EurekaClient来调用服务 <dependency> <groupId ...
- SpringCloud实战2-Ribbon客户端负载均衡
https://www.cnblogs.com/huangjuncong/p/9022055.html
- springcloud(十二):Ribbon客户端负载均衡介绍
springcloud(十二):Ribbon客户端负载均衡介绍 Ribbon简介 使用分布式微服务脚骨的应用系统,在部署的时候通常会为部分或者全部微服务搭建集群环境,通过提供多个实例来提高系统的稳定型 ...
- spring cloud --- Ribbon 客户端负载均衡 + RestTemplate + Hystrix 熔断器 [服务保护] ---心得
spring boot 1.5.9.RELEASE spring cloud Dalston.SR1 1.前言 当超大并发量并发访问一个服务接口时,服务器会崩溃 ,不仅导致这个接口无法 ...
- spring cloud --- Ribbon 客户端负载均衡 + RestTemplate ---心得【无熔断器】
spring boot 1.5.9.RELEASE spring cloud Dalston.SR1 1.前言 了解了 eureka 服务注册与发现 的3大角色 ,会使用RestTem ...
- SpringBoot(三) - Ribbon客户端负载均衡,Zuul网关,Config配置中心
1.Ribbon客户端负载均衡 1.1 依赖 1.2 配置信息 # feign默认加载了ribbon负载均衡,默认负载均衡机制是:轮询 # 负载均衡机制是添加在消费端(客户端)的,如果改为随机,指定服 ...
- ③SpringCloud 实战:使用 Ribbon 客户端负载均衡
这是SpringCloud实战系列中第三篇文章,了解前面第两篇文章更有助于更好理解本文内容: ①SpringCloud 实战:引入Eureka组件,完善服务治理 ②SpringCloud 实战:引入F ...
- SpringCloud系列之客户端负载均衡Netflix Ribbon
1. 什么是负载均衡? 负载均衡是一种基础的网络服务,它的核心原理是按照指定的负载均衡算法,将请求分配到后端服务集群上,从而为系统提供并行处理和高可用的能力.提到负载均衡,你可能想到nginx.对于负 ...
- 笔记:Spring Cloud Ribbon 客户端负载均衡
Spring Cloud Ribbon 是一个基于 HTTP 和 TCP 的客户端负载均衡工具,基于 Netflix Ribbon 实现,通过Spring Cloud 的封装,可以让我们轻松的将面向服 ...
随机推荐
- DB 查询分析器 6.04 发布 ,本人为之撰写的相关技术文章达78篇
DB查询分析器 6.04 发布,本人为之撰写的相关技术文章达78篇 中国本土程序员马根峰(CSDN专访马根峰:海量数据处理与分析大师的中国本土程序员 http://www.csdn.net/artic ...
- Oracle中添加自动编号的序列
1. 创建表T_Test create table T_Test(id int ,address char(25), pay int); 2. 创建自增序列 create sequence SEQ_ ...
- 基于VB中WINSOCK控件的网上象棋系统的实现
本文发表在<微型机与应用>杂志2001年第3期. 基于VB中WINSOCK控件的网上象棋系统的实现 马根峰1 , 孙艳2 , 王平1 (1.重庆邮电学院自动化学院,重庆,40006 ...
- 神奇的layout_weight属性
1.概述 在线性布局有时候为了控制一下屏幕的适配,可以使用layout_weight这个属性来设置权重,要注意一点,这个属性只有在Linearlayout中才有效,这个属性往往会随着android:l ...
- Oracle Service Bus白皮书
Oracle Service Bus简介 面对变幻莫测的市场需求的变化,企业希望通过推进"服务化"提高敏捷性和响应能力:更方便地与客户和合作伙伴交互,更灵活地设计和构建IT基础架构 ...
- "《算法导论》之‘字符串’":字符串匹配
本文主要叙述用于字符串匹配的KMP算法. 阮一峰的博文“字符串匹配的KMP算法"将该算法讲述得非常形象,可参考之. 字符串‘部分匹配值’计算 KMP算法重要的一步在于部分匹配值的计算.模仿& ...
- Android高级控件(四)——VideoView 实现引导页播放视频欢迎效果,超级简单却十分的炫酷
Android高级控件(四)--VideoView 实现引导页播放视频欢迎效果,超级简单却十分的炫酷 是不是感觉QQ空间什么的每次新版本更新那炫炫的引导页就特别的激动,哈哈,其实他实现起来真的很简单很 ...
- SharePoint"在数据表中编辑"不可用
报错: 没有安装与 Windows SharePoint Services 兼容的数据表组件 浏览器不支持 ActiveX 控件 或者禁用了对 ActiveX 控件的支持 第一反应,就是什么东西没装, ...
- Android为什么使用Binder-android学习之旅(101)
基础知识 Android进程和linux进程一样,他们只运行在进程固有的虚拟空间中.一个4GB的虚拟地址空间,其中3GB是用户空间,1GB是内核空间 ,用户空间是非共享的,内核空间是共享的,如下图: ...
- JAVA加密技术-----MD5 与SHA 加密
关于JAVA的加密技术有很多很多,这里只介绍加密技术的两种 MD5与 SHA. MD5与SHA是单向加密算法,也就是说加密后不能解密. MD5 ---信息摘要算法,广泛用于加密与解密技术,常用于文件校 ...