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负载均衡机制、手写轮询算法的更多相关文章

  1. Ribbon 负载均衡机制

    Ribbon 提供了几个负载均衡的组件,其目的就是让请求转给合适的服务器处理,因此,如何选择合适的服务器变成了负载均衡机制的核心,Ribbon 提供了如下负载均衡规则: RoundRobinRule: ...

  2. 负载均衡手段之DNS轮询

    大多数域名注册商都支持对统一主机添加多条A记录,这就是DNS轮询,DNS服务器将解析请求按照A记录的顺序,随机分配到不同的IP上,这样就完成了简单的负载均衡.下图的例子是:有3台联通服务器.3台电信服 ...

  3. SpringCloud Ribbon 负载均衡 通过服务器名无法连接的神坑一个

    一,问题 采取eureka集群.客户端通过Ribbon调用服务,Ribbon端报下列异常 java.net.UnknownHostException: SERVICE-HI java.lang.Ill ...

  4. Nginx做负载均衡的几种轮询策略

    集群环境为了解决单点无法支撑高并发的情况,集群采用多台服务器提供服务,一般在集群中使用nginx 将来自客户端的请求转发给服务器端 nginx负载均衡可用提高网站的吞吐量,缓解单台服务器的压力. 一. ...

  5. Nginx 做负载均衡的几种轮询策略

    网上看见nginx的upstream目前支持的5种方式的分配,摘录备忘. 1.轮询(默认)每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除.upstream back ...

  6. SpringCloud之Ribbon负载均衡策略

    Spring Cloud 微服务架构学习记录与示例 一.认识Ribbon 首先咱们需要认识下负载均衡,一般分为服务器端负载和客户端负载均衡. 服务器端负载均衡:比如Nginx.F5,请求达到服务器后由 ...

  7. 四. Ribbon负载均衡服务调用

    1. 概述 1.1 Ribbon是什么 SpringCloud Ribbon是基于Netflix Ribbon实现的一套客户端,是负载均衡的工具. Ribbon是Netflix发布的开源项目,主要功能 ...

  8. SpringCloud 服务负载均衡和调用 Ribbon、OpenFeign

    1.Ribbon Spring Cloud Ribbon是基于Netflix Ribbon实现的-套客户端―负载均衡的工具. 简单的说,Ribbon是Netlix发布的开源项目,主要功能是提供客户端的 ...

  9. SpringCloud系列——Ribbon 负载均衡

    前言 Ribbon是一个客户端负载均衡器,它提供了对HTTP和TCP客户端的行为的大量控制.我们在上篇(猛戳:SpringCloud系列——Feign 服务调用)已经实现了多个服务之间的Feign调用 ...

随机推荐

  1. RoBERTa

    2019-10-19 21:46:18 问题描述:谈谈对RoBERTa的理解. 问题求解: 在XLNet全面超越Bert后没多久,Facebook提出了RoBERTa(a Robustly Optim ...

  2. 条件随机场 CRF

    2019-09-29 15:38:26 问题描述:请解释一下NER任务中CRF层的作用. 问题求解: 在做NER任务的时候,神经网络学习到了文本间的信息,而CRF学习到了Tag间的信息. 加入CRF与 ...

  3. MySql最左匹配原则解析

    看前提问:table中有多个字段组成的联合索引(a,b,c),查询时哪些情况能够命中索引呢? 话不多说,直接开搞: 数据库表结构如下: CREATE TABLE `test` ( `id` ) uns ...

  4. BFS与DFS常考算法整理

    BFS与DFS常考算法整理 Preface BFS(Breath-First Search,广度优先搜索)与DFS(Depth-First Search,深度优先搜索)是两种针对树与图数据结构的遍历或 ...

  5. 使用PyTorch进行迁移学习

    概述 迁移学习可以改变你建立机器学习和深度学习模型的方式 了解如何使用PyTorch进行迁移学习,以及如何将其与使用预训练的模型联系起来 我们将使用真实世界的数据集,并比较使用卷积神经网络(CNNs) ...

  6. 十个python图像处理工具

    介绍 如今的世界存在了大量的数据,图像数据是重要的组成部分.如果要利用这些图片,需要对图像进行处理,提高图片质量或提取图片内容信息. 图像处理的常见操作包括图像显示,基本操作如裁剪,翻转,旋转等,图像 ...

  7. Centos7部署k8s[v1.16]高可用[keepalived]集群

    实验目的 一般情况下,k8s集群中只有一台master和多台node,当master故障时,引发的事故后果可想而知. 故本文目的在于体现集群的高可用,即当集群中的一台master宕机后,k8s集群通过 ...

  8. 【深度学习】Neural networks(神经网络)(一)

    神经网络的图解 感知机,是人工设置权重.让它的输出值符合预期. 而神经网络的一个重要性质是它可以自动地从数据中学习到合适的权重参数. 如果用图来表示神经网络,最左边的一列称为输入层,最右边的一列称为输 ...

  9. Failed RMAN Catalog Upgrade from 11.2.0.2 to 12.1.0.2 ( ORA-02296 RMAN-06004 )

    Failed RMAN Catalog Upgrade from 11.2.0.2 to 12.1.0.2  ( ORA-02296  RMAN-06004 ) 由于后期使用12c的数据库,需要对现有 ...

  10. [codeforces]Page Numbers <模拟>

    描述: «Bersoft» company is working on a new version of its most popular text editor — Bord 2010. Bord, ...