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 的封装,可以让我们轻松的将面向服 ...
随机推荐
- OJ题:字符串最后一个单词的长度
题目描述 计算字符串最后一个单词的长度,单词以空格隔开. 输入描述: 一行字符串,非空,长度小于5000. 输出描述: 整数N,最后一个单词的长度. 输入例子: hello world 输出例子: 5 ...
- 【leetcode75】Intersection of Two Arrays(数组的交集)
题目描述: 给定两个数组求他们的公共部分,输出形式是数组,相同的元素只是输出一次 例如: nums1 = [1, 2, 2, 1], nums2 = [2, 2], return [2]. 原文描述: ...
- R12 - Error 'Unable to process your transaction. The operating unit is either invalid or it cannot b
In this Document Symptoms Cause Solution Still Have Questions? References APPLIES TO: Orac ...
- ibatis 数据库时间 插入数据
<insert id="insert" parameterClass="ToDoBar" > <selectKey resultCla ...
- redis简介(keeper实时报表的基本部分)
网上有一篇介绍Redis的文章,由浅入深地讲解了Redis:http://blog.mjrusso.com/2010/10/17/redis-from-the-ground-up.html.强烈建议对 ...
- Linux备份策略(第二版)
备份策略 备份思想 一.系统潜在的威胁 Ø 系统硬件故障 Ø 软件故障 Ø 电源故障 Ø 用户的误操作 Ø 人为破坏 Ø 缓存中的内容没有及时的写入磁盘 Ø 自然灾害 二.备份介质的选择 备份介质:硬 ...
- SpriteBuilder物理对象的父子关系
注意:打开物理使能(Physics-enabled)的节点忽略他们的父节点关系. 这意味着,一个物理使能的子节点不会随着其父节点移动. 物理引擎对于节点父子关系这个概念毫不知情,因此单独的对待所有物理 ...
- C语言之归并排序
即将两个都升序(或降序)排列的数据序列合并成一个仍按原序排列的序列. 上代码: #include <stdio.h> #include <stdlib.h> #define m ...
- Objective-C的面向对象特性(二)
在Objective-C语言中, 类别.类扩展(也称为匿名类别)以及协议是Objective-C 语言级别支持的模式,用来实现对类进行功能扩展. 一.类别--用来增加方法到已存在类 声明一个类别的语法 ...
- 单片机驱动AT24C02存储芯片
AT24C02是一个2K位串行CMOS E2PROM, 内部含有256个8位字节,CATALYST公司的先进CMOS技术实质上减少了器件的功耗.AT24C02有一个8字节页写缓冲器.该器件通过IIC总 ...