Spring Cloud 入门 之 Ribbon 篇(二)
原文地址:Spring Cloud 入门 之 Ribbon 篇(二)
博客地址:http://www.extlight.com
一、前言
上一篇《Spring Cloud 入门 之 Eureka 篇(一)》 介绍了微服务的搭建,服务注册与发现。但在文章中留了一个小尾巴--如何正确使用 Eureka 进行服务发现并调用服务。
本篇文章将介绍如何使用 Ribbon 完成发现服务的调用以及其负载均衡的规则的使用。
二、简单介绍
Spring Cloud Ribbon 是基于 Netflix Ribbon 实现的一套客户端负载均衡工具,其主要功能是提供客户端的软件负载均衡算法,将 Netflix 的中间层服务连接在一起。
其运行原理如下图:

Ribbon 运行时分成 2 个步骤:
1) 先选择在同一个区域负载较少的 EurekaServer;
2) 再根据用户指定的策略,在从 EurekaServer 中获取注册列表中的服务信息进行调用。
其中,Ribbon 提供多种负载均衡策略:如轮询、随机、响应时间加权等。
三、实战演练
我们在 order-server 项目的基础上进行修改。不清楚的读者请先转移至 《Spring Cloud 入门 之 Eureka 篇(一)》 进行浏览。
此外,笔者额外的创建 2 个 goods-server 项目,即现在有 3 个 goods-server 项目给 order-server 服务实现客户端的负载均衡调用。
现在的项目列表如下:
| 服务实例 | 端口 | 描述 |
|---|---|---|
| common-api | - | 公用的 api,如:实体类 |
| eureka-server | 9000 | 注册中心(Eureka 服务端) |
| goods-server | 8081 | 商品服务(Eureka 客户端) |
| goods-server-02 | 8082 | 商品服务(Eureka 客户端) |
| goods-server-03 | 8083 | 商品服务(Eureka 客户端) |
| order-server | 8100 | 订单服务(Eureka 客户端) |
在 order-server 项目中:
- 添加依赖:
<dependencies>
<!-- common api -->
<dependency>
<groupId>com.extlight.springcloud</groupId>
<artifactId>common-api</artifactId>
<version>${parent-version}</version>
</dependency>
<!-- springmvc -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- eureka 客户端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- ribbon -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
</dependencies>
添加加 ribbon 的依赖。
- 请求类添加 @LoadBalanced 注解:
@Configuration
public class RestConfiguration {
@Bean
@LoadBalanced
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}
正如上文介绍的,Ribbon 是客户端负载均衡工具,所以在 getRestTemplate 方法上添加 @LoadBalanced 注解实现负载均衡。
- 修改请求地址:
@Service
public class OrderServiceImpl implements OrderService{
@Autowired
private RestTemplate restTemplate;
// @Autowired
// private DiscoveryClient client;
@Override
public void placeOrder(Order order) throws Exception{
// 获取商品服务地址列表
// List<ServiceInstance> list = this.client.getInstances("GOODS");
// String uri = "";
// for (ServiceInstance instance : list) {
// if (instance.getUri() != null && !"".equals(instance.getUri())) {
// uri = instance.getUri().toString();
// break;
// }
// }
//
// Result result = restTemplate.getForObject(new URI(uri + "/goods/goodsInfo/" + order.getGoodsId()), Result.class);
Result result = this.restTemplate.getForObject("http://GOODS/goods/goodsInfo/" + order.getGoodsId(), Result.class);
if (result != null && result.getCode() == 200) {
System.out.println("=====下订单====");
System.out.println(result.getData());
}
}
}
修改 DiscoveryClient 相关代码,使用 GOODS 作为请求商品服务的请求 URL。
完成上边 3 个操作后,启动 3 台 goods-server 服务 和 order-server 服务,通过 Postman 进行测试,运行结果如下:

上图中,通过 6 次请求返回的商品的端口信息可知,Ribbon 默认使用负载均衡的策略是轮询,对服务进行调用。
四、负载均衡策略
4.1 策略规则
Ribbon 提供 IRule 接口,该接口定义了如何访问服务的方法,以下是该接口的实现类:
1) RoundRobinRule:轮询,默认使用的规则;
2) RandomRule:随机;
3) AvailabilityFilteringRule:先过滤由于多次访问故障而处于断路器跳闸状态以及并发连接数量超过阀值得服务,然后从剩余服务列表中按照轮询策略进行访问;
4) WeightedResponseTimeRule:根据平均响应时间计算所有的权重,响应时间越快服务权重越有可能被选中;
5) RetryRule:先按照 RoundRobinRule 策略获取服务,如果获取服务失败则在指定时间内进行重试,获取可用服务;
6) BestAvailableRule:先过滤由于多次访问故障而处于断路器跳闸状态的服务,然后选择并发量最小的服务;
7) ZoneAvoidanceRule:判断 server 所在区域的性能和 server 的可用性来选择服务器。
4.2 策略使用
在 order-server 项目中:
@Configuration
public class RestConfiguration {
@Bean
@LoadBalanced
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
@Bean
public IRule testRule() {
return new RandomRule();
}
}
手动创建负载均衡规则对象,本次测试使用的策略是随机。
启动 order-server 项目后再次使用 Postman 测试,运行结果如下:

由图可知,随机策略已生效,负载均衡的策略由轮询变成了随机。
五、案例源码
Spring Cloud 入门 之 Ribbon 篇(二)的更多相关文章
- Spring Cloud 入门 之 Feign 篇(三)
原文地址:Spring Cloud 入门 之 Feign 篇(三) 博客地址:http://www.extlight.com 一.前言 在上一篇文章<Spring Cloud 入门 之 Ribb ...
- Spring Cloud 入门 之 Zuul 篇(五)
原文地址:Spring Cloud 入门 之 Zuul 篇(五) 博客地址:http://www.extlight.com 一.前言 随着业务的扩展,微服务会不对增加,相应的其对外开放的 API 接口 ...
- Spring Cloud 入门 之 Eureka 篇(一)
原文地址:Spring Cloud 入门 之 Eureka 篇(一) 博客地址:http://www.extlight.com 一.前言 Spring Cloud 是一系列框架的有序集合.它利用 Sp ...
- Spring Cloud 入门 之 Config 篇(六)
原文地址:Spring Cloud 入门 之 Config 篇(六) 博客地址:http://www.extlight.com 一.前言 随着业务的扩展,为了方便开发和维护项目,我们通常会将大项目拆分 ...
- Spring Cloud 入门 之 Hystrix 篇(四)
原文地址:Spring Cloud 入门 之 Hystrix 篇(四) 博客地址:http://www.extlight.com 一.前言 在微服务应用中,服务存在一定的依赖关系,如果某个目标服务调用 ...
- Spring Cloud入门教程-Ribbon实现客户端负载均衡
简介 我们继续以之前博客的代码为基础,增加Ribbon组件来提供客户端负载均衡.负载均衡是实现高并发.高性能.可伸缩服务的重要组成部分,它可以把请求分散到一个集群中不同的服务器中,以减轻每个服务器的负 ...
- <Spring Cloud>入门三 Ribbon
1.Ribbon 客户端软负载均衡组件 1.1配置 搭建了三个消费者供客户端调用: 1.修改yml eureka: client: service-url: defaultZone: http://e ...
- Spring Cloud入门教程(二):客户端负载均衡(Ribbon)
对于大型应用系统负载均衡(LB:Load Balancing)是首要被解决一个问题.在微服务之前LB方案主要是集中式负载均衡方案,在服务消费者和服务提供者之间又一个独立的LB,LB通常是专门的硬件,如 ...
- Spring Cloud 入门教程(五): Ribbon实现客户端的负载均衡
接上节,假如我们的Hello world服务的访问量剧增,用一个服务已经无法承载, 我们可以把Hello World服务做成一个集群. 很简单,我们只需要复制Hello world服务,同时将原来的端 ...
随机推荐
- 20145105 《Java程序设计》第5周学习总结
20145105 <Java程序设计>第5周学习总结 教材学习内容总结 第八章 异常处理 一.语法与继承架构 (一)使用try.catch 执行流程 尝试执行try区块中程序代码 如果出现 ...
- 20145329 《网络对抗技术》MS08_067远程漏洞攻击
MS08_067远程漏洞攻击:shell 实现攻击的前提是:攻击机和靶机在同一个网段下,首先将kali的ip改为与winxp的ip一样,二者能ping通 两台虚拟机: kali ip:192.168. ...
- 2017-2018-1 Java小组-1623 第一周作业
2017-2018-1 Java小组-1623 第一周作业 <构建之法>学习笔记及团队成员介绍 1. 学习内容 概论 个人技术和流程 软件工程师的成长 两人合作 团队和流程 敏捷流程 实战 ...
- java中static关键字的使用
知识点:java中,static关键字修饰类的变量.方法.代码块.内部类 场景:我们在创建类的方法和变量时,如果这个类在创建多个对象时,共用同一个属性或者方法,就可以使用static关键字修饰,因为s ...
- P4 PI库安装
repo:Github PI P4Runtime - a control plane framework and tools for the P4 programming language 这个是P4 ...
- POJ 1170 Shopping Offers(完全背包+哈希)
http://poj.org/problem?id=1170 题意:有n种花的数量和价格,以及m种套餐买法(套餐会便宜些),问最少要花多少钱. 思路:题目是完全背包,但这道题目不好处理的是套餐的状态, ...
- python 使用两个列表合成字典
keys = ['red', 'green', 'blue'] values = ['#FF0000','#008000', '#0000FF'] color_dictionary = dict(zi ...
- 日志_测试代码_Delphi7
1. 2.Delphi (Windows API 文件尾部添加) function LogFile(_str :string) :integer; var hFile :THandle; strFil ...
- JVM知识总结-运行时区域划分
区域简介 JVM运行时区域有些随着虚拟机进程的启动而存在,有些依赖于用户线程的启动和结束而建立和销毁,大致分为以下几类:方法区,虚拟机栈,本地方法栈,堆,程序计数器,概念图如下(源于<深入理解J ...
- Web开发中的显示与隐藏
大多数编程语言,在平开发过程中,都是会遇到一些特殊的场景,需要实现显示或者隐藏来达到我们想要的效果:然而实现的方式有多种,今天就写一下,希望可以帮到各位. 小编我学习前端1年了,特意写写博客来回顾一下 ...