负载均衡 —— SpringCloud Netflix Ribbon
Ribbon 简介
Ribbon 是 Netfix 客户端的负载均衡器,可对 HTTP 和 TCP 客户端的行为进行控制。为 Ribbon 配置服务提供者地址后,Ribbon 就可以基于某种负载均衡算法自动帮助服务消费者去请求。Ribbon 默认提供了很多负载均衡算法,例如轮询、随机等,也可以为 Ribbon 实现自定义的负载均衡算法
Ribbon 有以下几个重要概念:
- Rule:该组件主要决定从候选服务器中返回哪个服务器地址进行远程调用的操作
- Ping:在后台运行的组件,用来确认哪些服务器是存活可用的
- ServerList:当前可以用作 LB 的服务器列表,该列表可以是静态的,也可以是动态的。如果是动态列表(例如从 Eurka 服务器获取),就会有一个后台线程按照时间间隔刷新列表
Ribbon 提供了以下几种 Rule:
- RoundRobinRule:最简单的规则,会在 ServerList 中依次轮询调用
- RandomRule:随机
- AvailabilityFileringRule:在这种规则下 Ribbon 集成了 Hystrix 的功能,默认情况下调用某个远程方法失败三次后断路器的开关会被打开,而之后的请求中 Ribbon 会跳过这个服务器地址,直到三十秒之后断路器关闭后才会重新加入调用列表
- WeightedResponseTimeRule:将响应时间作为权重的负载规则,某个服务器的响应时越长,它的权重就越低,具体选择服务器时,结合权重进行随机选择
- RetryRule:按照 RoundRobinRule(轮询)策略获取服务,如果获取服务失败,就在指定时间内重试,获取可用的服务
- BestAvailableRule:先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务
- ZoneAvoidanceRule:复合判断 Server 所在区域的性能和 Server 的可用性选择服务器
负载均衡算法
服务消费者从服务配置中心获取服务的地址列表后需要选取其中一台发起 RPC/HTTP 调用,这时需要用到具体的负载均衡算法
1. 轮询法
轮询法是指将请求按顺序轮流分配到后端服务器上,均衡地对待后端的每一台服务器,不关心服务器实际的连接数和当前系统负载
2. 加权轮询法
简单的轮询法并不考虑后端机器的性能和负载差异,加权轮询法可以很好地处理这一问题,它将按照顺序且按照权重分派给后端服务器,给性能高、负载低的机器配置较高的权重,让其处理较多的请求,给性能低、负载高的机器配置较低的权重,让其处理较少的请求
假设有 9 个客户端请求、3 台后端服务器,后端服务器 1 被赋予权值 1,后端服务器2被赋予值 2,后端服务器 3 赋值 3,这样一来,客户端请求 1、2、3 都被分派到服务器 3 处理,客户端请求 4、5 被分派到服务器 2 处,客户端请求 6 被分派到服务器 1 处理,客户端请求 7、8、9 被分派到服务器 3 处理,以此类推
3. 随机法
随机法也很简单,就是随机选择一台后端服务器进行请求处理,由于每次服务器被挑中的概率都一样,因此客户端的请求可以被均匀地分派到所有的后端服务器上
4. 加权随机法
加权随机法跟加权轮询法类似,根据后台服务器不同的配置和负载情况配置不同的权重,不同的是,它是按照权重来随机选取服务器的,而非顺序
比如希望抽到 A 的概率是 50%、抽到 B 和 C 的概率是 20%、抽到 D 的概率是 10%,一般来说,我们可以给各项附加一个权重,抽取的概率正比于这个权重,上述集合就成了 {A:5,B:2,C:2,D:1),扩展这个集合,使每一项出现的次数与其权重正相关,即 {A,A,A,A,A,B,BC,C,D},然后就可以用均匀随机算法从中选取了
5. 源地址哈希法
源地址哈希是根据获取客户端的 IP 地址,通过哈希函数计算得到一个数值,用该数值对服务器列表的大小进行取模运算,得到的结果便是客户端要访问服务器的序号。采用源地址哈希法进行负载均衡,当后端服务器列表不变时,同一个 IP 地址的客户端,每次都会映射到同一台后端服务器进行访问,但当后端服务器增加或者减少时,由于次数用于取模的服务器总数发生了变化,就导致同一哈希值的请求无法命中同一台服务器,节点数越高,命中率越低
6. 一致性哈希法
一致性哈希法解决了分布式环境下机器增加或者减少时简单的取模运算无法获取较高命中率的问题,通过一个一致性哈希环的数据结构实现映射,具体算法过程为:先构造一个长度为 2 的 32 次方的整数环(一致性哈希环),根据节点计算得出的哈希值将缓存服务器节点放置在这个哈希环上,然后在哈希环上顺时针查找距离这个哈希值最近的服务器节点,完成请求到服务器的映射

假设现在增加一台服务器 4,那么影响的就只有一个的请求,也就是说原本到服务器 1 的请求会被映射到服务器 4 上,虽然也会影响到整个集群,但是影响的只是加粗的那一段而已,这种影响要小得多。更重要的是,集群中缓存服务器节点越多,增加节点带来的影响越小

第一个 Ribbon 程序
创建名为 ribbon-provider 的项目,添加配置文件 application-01.properties 和 application-02.properties
# application-01.properties 配置文件内容
server.port=8080
# application-02.properties 配置文件内容
server.port=8081
开发 UserController 类
@RestController
@RequestMapping("user")
public class UserCon {
@Resource
private Environment environment;
public String getPort() {
return environment.getProperty("local.server.port");
}
@RequestMapping("getName")
public String getUserName (){
return "hello,ay" + "-" + getPort();
}
}
通过使用不同的配置文件,可以启动多个 SpringBoot 应用,分别启动 ribbon-provider-8080 和 ribbon-provider-8081
创建名为 ribbon-consumer 的项目,pom.xml 添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
添加配置文件 application.yml
my-client: #负载均衡配置
ribbon:
listOfServers: localhost:8080,localhost:8081 # 配置服务列表
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule # 配置负载均衡算法 RoundRobinRule(轮询)
Ribbon 的配置格式是 <clientName>:ribbon:需要配置的属性,<clientName> 是 Ribbon 的客户端名称,如果省略就配置所有客户端,配置的属性有以下几种:
- NFLoadBalancerClassName:配置 ILoadBalancer 的实现类
- NFLoadBalancerRuleClassName:配置 IRule 的实现类
- NFLoadBalancerPingClassName:配置 IPing 的实现类
- NIWSServerListClassName:配置 ServerList 的实现类
- NIWSServerListFilterClassName:配置 ServerListFilter 的实现类
在 main 方法中添加如下代码:
@SpringBootApplication
public class RibbonConsumerApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(RibbonConsumerApplication.class, args);
//获取客户端
RestClient client = (RestClient) ClientFactory.getNamedClient("my-client");
//调用UserController类的getUserName 方法
HttpRequest request = HttpRequest.newBuilder().uri("/user/getName").build();
//循环调用
for(int i = 0; i<10; i++) {
HttpResponse response = client.executeWithLoadBalancer(request);
String result = response.getEntity(String.class);
System.out.println(result);
}
}
}
启动 ribbon-consumer 项目,从打印信息中可以看出,服务通过轮询的方式调用
Ribbon 整合 Nacos & 自定义负载均衡策略
创建 ribbon-custom-consumer 的项目,添加配置类
@Configuration
public class RibbonConfig {
@Bean
public IRule ribbonRule() {
// ribbon默认使用的是zoneAvoidanceRule规则,这里修改为自定义方式
return new MyRule();
}
}
创建 MyRule 类,用来自定义负载均衡规则
/**
* 负载规则:始终返回第一个服务
*/
public class MyRule extends AbstractLoadBalancerRule {
@Override
public void initWithNiwsConfig(IClientConfig iClientConfig) {
}
@Override
public Server choose(Object o) {
ILoadBalancer loadBalancer = getLoadBalancer();
// 获取所有的服务
List<Server> servers = loadBalancer.getAllServers();
// 始终返回第一个服务
return servers.get(0);
}
}
自定义指定 Ribbon 客户端的配置
/**
* 使用 RibbonClient 为特定 name 的 Ribbon Client 自定义配置
* 使用 @RibbonClient 的 configuration 属性指定 Ribbon 的配置类
*/
@Configuration
@RibbonClient(name = "service-provider", configuration = RibbonConfig.class)
public class TestConfig {
}
在 application.properties 配置文件中添加如下配置
server.port=7089
spring.application.name=service-custom
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
在启动类中添加 @EnableDiscoveryClient 注解
@EnableDiscoveryClient
@SpringBootApplication
public class RibbonCustomApplication {
public static void main(String[] args) {
SpringApplication.run(RibbonCustomApplication.class, args);
}
}
创建 TesController类,具体代码如下
@RestController
@RequestMapping("test")
public class TestController {
@Resource
private LoadBalancerClient loadBalancerClient;
@RequestMapping("getUserName")
public String getUserName() {
for (int i = 0; i < 20; i++) {
//获取service-provider服务
ServiceInstance serviceInstance = loadBalancerClient.choose("service-provider");
//打印当前选择的是哪个节点
System.out.println(serviceInstance.getServiceId() + serviceInstance.getHost() + "; " + serviceInstance.getPort());
}
return "hello,ay";
}
}
在上述步骤中,我们创建了 ribbon-custom-consumer 项目,并定义了负载均衡规则 MyRule,服务启动后注册到 Nacos 中,这样一来,在调用 getUserName 方法时,会从 Nacos 中获取已注册的服务提供者列表,并按照我们自定义的负载规则进行调用
负载均衡 —— SpringCloud Netflix Ribbon的更多相关文章
- SpringCloud Netflix Ribbon
Eureka客户端的负载均衡:从Eureka server拿到节点列表,客户端自己使用负载均衡的算法确定要使用的节点: Eureka服务端的负载均衡:服务端使用负载均衡的算法,从节点列表中确定要使用的 ...
- SpringCloud Netflix Ribbon(负载均衡)
⒈Ribbon是什么? Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡工具. Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负 ...
- SpringCloud系列五:Ribbon 负载均衡(Ribbon 基本使用、Ribbon 负载均衡、自定义 Ribbon 配置、禁用 Eureka 实现 Ribbon 调用)
1.概念:Ribbon 负载均衡 2.具体内容 现在所有的服务已经通过了 Eureka 进行了注册,那么使用 Eureka 注册的目的是希望所有的服务都统一归属到 Eureka 之中进 行处理,但是现 ...
- SpringCloud(三):服务消费以及负载均衡(RestTemplate+Ribbon)
一.什么是Ribbon: Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法. 将Netflix的中间层服务连接在一起.Ribbon客户端组件提供一系列完善的配置项如连 ...
- SpringCloud 服务负载均衡和调用 Ribbon、OpenFeign
1.Ribbon Spring Cloud Ribbon是基于Netflix Ribbon实现的-套客户端―负载均衡的工具. 简单的说,Ribbon是Netlix发布的开源项目,主要功能是提供客户端的 ...
- 【SpringCloud微服务实战学习系列】客户端负载均衡Spring Cloud Ribbon
Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon实现.通过Spring Cloud的封装,可以让我们轻松地将面向服务的RES模板 ...
- 玩转Spring Cloud之服务注册发现(eureka)及负载均衡消费(ribbon、feign)
如果说用Spring Boot+Spring MVC是开发单体应用(或单体服务)的利器,那么Spring Boot+Spring MVC+Spring Cloud将是开发分布式应用(快速构建微服务)的 ...
- SpringCloud学习笔记(四、SpringCloud Netflix Ribbon)
目录: Ribbon简介 Ribbon的应用 RestTemplate简介 Ribbon负载均衡源码分析 Ribbon简介: 1.负载均衡是什么 负载均衡,根据其字面意思来说就是让集群服务具有共同完成 ...
- SpringCloud---客户端负载均衡---Spring Cloud Ribbon
1.概述 1.1 Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具: 基于Netflix Ribbon实现: 通过Spring Cloud的封装,可以轻松将面向服务 ...
- Spring Cloud ---- 服务消费与负载均衡(Rest + Ribbon )
上一篇主要写了基于Eurake的服务的注册,主要就是创建注册中心,创建服务者,将服务者注册到注册中心,完成服务的暴露.这一篇主要写服务的消费与服务消费的负载均衡. 服务的调用方式有两种,Rest + ...
随机推荐
- 题解 ARC104F
前言 在这里首先感谢一下题解区的 FZzzz,本人的题解思路主要是基于他并给出了自己的理解. 如非特殊说明,本题解中的数学符号原则上与题目中一致. 题目分析 需要转化的喵喵题. 我们需要把原问题转化成 ...
- JS 树形结构 根据子节点找到所有上级
需求:是根据子菜单找到所有他上级菜单 进行面包屑的回显 要求子节点里包含父级id 代码如下: parentTree(arr, id) { //arr 所有的树数据 id 某个子节点的id ...
- Python中的爬虫应用及常用Python库
Python的爬虫应用非常广泛,以下是一些典型的示例: 数据采集:使用爬虫可以从网页上抓取数据,并将其保存到本地或数据库中.这对于构建大规模数据集.进行市场调研.舆情监测等任务非常有用. 搜索引擎索引 ...
- 一个Blazor+WinForm+MAUI+PDA实现的条码比对系统
条码比对系统是由单机版桌面软件和Android版的PDA扫码软件组成,桌面软件采用Blazor与WinForm进行混合开发,PDA扫码软件采用MAUI进行开发,这个项目都是基于.NET技术进行构建,这 ...
- 「有问必答」秒杀系统 Go并发编程实践!
有问必答 摘要 本文将介绍如何使用Go语言的并发原语来构建一个简单的高并发秒杀系统. 我们将使用Go语言的原生库和一些常见的技术手段,包括互斥锁.通道.计数器等,来解决并发访问和数据一致性的问题. 本 ...
- 【Android】Android Bmob后端云配置
简介 开发一个具有网络功能的应用,在Bmob移动应用云存储平台中,只需要注册一个账号,就可以实现申请创建任意多个数据库,获得对应的key,下载对应版本的SDK,并嵌入到移动应用中,调用存取的KPI,进 ...
- 数据结构(C语言版 第2版)课后习题答案全集 严蔚敏
有的小伙伴在网上奋力的找 严蔚敏版 第2版 数据结构 的始终无果,那么我这里就整理好,放在同名公众号中了,也可扫文章末尾的二维码直达公众号,回复数据结构的关键词即可拿到.
- 基于WPSOffice+Pywpsrpc构建Docker镜像,实现文档转换和在线预览服务
背景 产品功能需要实现标准文档的在线预览功能,由于DOC文档没办法直接通过浏览器打开预览,需要提前转换为PDF文档或者HTML页面. 经过测试发现DOC转为HTML页面后文件提交较大,而且生成的静态资 ...
- springboot操作nosql的mongodb,或者是如何在mongodb官网创建服务器并进行操作
第一步:在mongodb的官网里面创建云服务器 点进去 这是免费的,由于是一个项目只可以创建一个,这里我已经创建好了 用本地的mongodb服务也是可以的 第二步:点击connect,下载连接mong ...
- Lucas定理 、斯特灵公式
斯特灵公式是一条用来取n阶乘的近似值的数学公式. 公式为: 用该公式我们可以用来估算n阶乘的值:估算n阶乘的在任意进制下的位数. 如何计算在R进制下的位数:我们可以结合对数来计算,比如十进制就是lg( ...