SpringCloud-Ribbon负载均衡机制、手写轮询算法
Ribbon 内置的负载均衡规则
在 com.netflix.loadbalancer 包下有一个接口 IRule,它可以根据特定的算法从服务列表中选取一个要访问的服务,默认使用的是「轮询机制」

- RoundRobinRule:轮询
- RandomRule:随机
- RetryRule:先按照
RoundRobinRule的策略获取服务,如果获取服务失败则在指定时间内会进行重试,获取可用的服务 - WeightedResponseTimeRule:对
RoundRobinRule的扩展,响应速度越快的实例选择权重越大,越容易被选择 - BestAvailableRule:会过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务
- AvailabilityFilteringRule:先过滤掉故障实例,再选择并发较小的实例
- ZoneAvoidanceRule:默认规则,复合判断 server 所在区域的性能和 server 的可用性选择服务器
负载规则的替换
如果不想使用 Ribbon 默认使用的规则,我们可以通过自定义配置类的方式,手动指定使用哪一种。
需要注意的是,自定义配置类不能放在 @ComponentScan 所扫描的当前包下以及子包下,否则我们自定义的这个配置类就会被所有的 Ribbon 客户端所共享,达不到特殊化定制的目的了。
因此我们需要在 Spring Boot 启动类所在包的外面新建一个包存放自定义配置类
@Configuration
public class MyselfRule {
@Bean
public IRule rule(){
//随机
return new RandomRule();
}
}
然后在启动类上添加如下注解,指定服务名及自定义配置类
@RibbonClient(value = "CLOUD-PAYMENT-SERVICE", configuration = MyselfRule.class)
Ribbon 默认负载轮询算法的原理
算法概述
rest 接口第几次请求数 % 服务器集群总个数 = 实际调用服务器位置下标,服务每次重启后 rest 请求数变为1
源码
public Server choose(ILoadBalancer lb, Object key) {
if (lb == null) {
log.warn("no load balancer");
return null;
}
Server server = null;
int count = 0;
//循环获取服务,最多获取10次
while (server == null && count++ < 10) {
List<Server> reachableServers = lb.getReachableServers();
List<Server> allServers = lb.getAllServers();
//开启的服务个数
int upCount = reachableServers.size();
int serverCount = allServers.size();
if ((upCount == 0) || (serverCount == 0)) {
log.warn("No up servers available from load balancer: " + lb);
return null;
}
//计算下一个服务的下标
int nextServerIndex = incrementAndGetModulo(serverCount);
server = allServers.get(nextServerIndex);
if (server == null) {
/* Transient. */
Thread.yield();
continue;
}
if (server.isAlive() && (server.isReadyToServe())) {
return (server);
}
// Next.
server = null;
}
if (count >= 10) {
log.warn("No available alive servers after 10 tries from load balancer: "
+ lb);
}
return server;
}
//通过此方法获取服务的下标,使用了 CAS 和自旋锁
private int incrementAndGetModulo(int modulo) {
for (;;) {
int current = nextServerCyclicCounter.get();
int next = (current + 1) % modulo;
if (nextServerCyclicCounter.compareAndSet(current, next))
return next;
}
}
手写轮询算法
在服务提供者写一个方法,返回端口号看效果就行
@GetMapping("/payment/lb")
public String roundLb(){
return this.serverPort;
}
负载均衡接口
public interface LoadBalancer {
/**
* 获取服务实例
*/
ServiceInstance getInstance(List<ServiceInstance>serviceInstances);
}
算法实现类
@Component
public class MyLb implements LoadBalancer {
private AtomicInteger atomicInteger = new AtomicInteger(0);
/**
* 使用「自旋锁」和「CAS」增加请求次数
*/
public final int incrementAndGet() {
int current;
int next;
do {
current = atomicInteger.get();
//防溢出
next = current >= Integer.MAX_VALUE ? 0 : current + 1;
} while (!atomicInteger.compareAndSet(current, next));
return next;
}
@Override
public ServiceInstance getInstance(List<ServiceInstance> serviceInstances) {
// 实际调用服务器位置下标 = rest 接口第几次请求数 % 服务器集群总个数
int index = incrementAndGet() % serviceInstances.size();
return serviceInstances.get(index);
}
}
编写服务消费者方法,记得注释 @LoadBalanced 注解,否则不生效
@GetMapping("/consumer/payment/lb")
public String roundLb(){
List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
if (instances == null || instances.size() <= 0){
return null;
}
ServiceInstance instance = loadBalancer.getInstance(instances);
URI uri = instance.getUri();
return restTemplate.getForObject(uri + "/payment/lb", String.class);
}
SpringCloud-Ribbon负载均衡机制、手写轮询算法的更多相关文章
- Ribbon 负载均衡机制
Ribbon 提供了几个负载均衡的组件,其目的就是让请求转给合适的服务器处理,因此,如何选择合适的服务器变成了负载均衡机制的核心,Ribbon 提供了如下负载均衡规则: RoundRobinRule: ...
- 负载均衡手段之DNS轮询
大多数域名注册商都支持对统一主机添加多条A记录,这就是DNS轮询,DNS服务器将解析请求按照A记录的顺序,随机分配到不同的IP上,这样就完成了简单的负载均衡.下图的例子是:有3台联通服务器.3台电信服 ...
- SpringCloud Ribbon 负载均衡 通过服务器名无法连接的神坑一个
一,问题 采取eureka集群.客户端通过Ribbon调用服务,Ribbon端报下列异常 java.net.UnknownHostException: SERVICE-HI java.lang.Ill ...
- Nginx做负载均衡的几种轮询策略
集群环境为了解决单点无法支撑高并发的情况,集群采用多台服务器提供服务,一般在集群中使用nginx 将来自客户端的请求转发给服务器端 nginx负载均衡可用提高网站的吞吐量,缓解单台服务器的压力. 一. ...
- Nginx 做负载均衡的几种轮询策略
网上看见nginx的upstream目前支持的5种方式的分配,摘录备忘. 1.轮询(默认)每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除.upstream back ...
- SpringCloud之Ribbon负载均衡策略
Spring Cloud 微服务架构学习记录与示例 一.认识Ribbon 首先咱们需要认识下负载均衡,一般分为服务器端负载和客户端负载均衡. 服务器端负载均衡:比如Nginx.F5,请求达到服务器后由 ...
- 四. Ribbon负载均衡服务调用
1. 概述 1.1 Ribbon是什么 SpringCloud Ribbon是基于Netflix Ribbon实现的一套客户端,是负载均衡的工具. Ribbon是Netflix发布的开源项目,主要功能 ...
- SpringCloud 服务负载均衡和调用 Ribbon、OpenFeign
1.Ribbon Spring Cloud Ribbon是基于Netflix Ribbon实现的-套客户端―负载均衡的工具. 简单的说,Ribbon是Netlix发布的开源项目,主要功能是提供客户端的 ...
- SpringCloud系列——Ribbon 负载均衡
前言 Ribbon是一个客户端负载均衡器,它提供了对HTTP和TCP客户端的行为的大量控制.我们在上篇(猛戳:SpringCloud系列——Feign 服务调用)已经实现了多个服务之间的Feign调用 ...
随机推荐
- python爬取中国大学排名
教程来自:[Python网络爬虫与信息提取].MOOC. 北京理工大学 目标:爬取最好大学网前50名大学 代码如下: import requests from bs4 import Beautiful ...
- mac下 yarn Stack trace: ExitCodeException exitCode=127
问题出在hadoop 为mac系统配置的读取java_home处. 更改 /Users/shaofengfeng/apache/hadoop/libexec/hadoop-config.sh 如下 # ...
- 力软敏捷框架7.0.6 葡萄城报表升级到ar14版本
忙了两天终于搞定升级到ar14版本,坑无数,终于算全部解决,在这里做一个小结. 1.第一步去掉框架中原本集成的ar13部分(吐槽一下应该是对12的集成). 首先去掉licenses.licx文件. 然 ...
- Go语言库系列之flag
背景 终端(命令行)操作是程序员的必备技能,但是你知道怎么通过golang制作出如下命令吗? $ flag girl -h Usage of girl: -height int 身高 (default ...
- SVM多核学习方法简介
作者:Walker SVM是机器学习有监督学习的一种方法,常用于解决分类问题,其基本原理是:在特征空间里寻找一个超平面,以最小的错分率把正负样本分开.因为SVM既能达到工业界的要求,机器学习研究者又能 ...
- iOS OCR
身份证识别,又称 OCR 技术.OCR 技术是光学字符识别的缩写,是通过扫描等光学输入方式将各种票据.报刊.书籍.文稿及其它印刷品的文字转化为图像信息,再利用文字识别技术将图像信息转化为可以使用的计算 ...
- linux进程和线程直接通信方式梳理
对于linux的进程之间.线程直接的通信方式进行梳理,这些都属于基本知识,不过因为知识体系“年久失修”,需要重新总结汇总.
- 【3D】PoseCNN姿态检测网络复现过程记录
最近在研究室内6D姿态检测相关问题,计划在PoseCNN网络基础上进行改进实现.但是在第一步的复现过程中踩了无数的坑,最终成功运行了demo,但目前数据集train还是遇到了一些问题.有问题欢迎一起交 ...
- Python中的编码及操作文件
------------恢复内容开始------------ 1,字符编码 ASCII 用1个字符来表示所有的英文字母和特殊符号 GB2313(GBK)用2个字符来表示英文字母及中文字符,且决定如果 ...
- Sql练习201908200918
表结构: 昨天遇到一个笔试题,求一个聚合函数小于等于1000的值,并将编号同时输出. sql server: select nid,SUM(amount) amountSum from orders_ ...