【微服务六】Ribbon负载均衡策略之轮询(RoundRobinRule)、重试(RetryRule)

本文涉及的产品
云原生网关 MSE Higress,422元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
注册配置 MSE Nacos/ZooKeeper,118元/月
简介: 【微服务六】Ribbon负载均衡策略之轮询(RoundRobinRule)、重试(RetryRule)

@[TOC]

一、前言

前置Ribbon相关文章:

  1. 【云原生&微服务一】SpringCloud之Ribbon实现负载均衡详细案例(集成Eureka、Ribbon)
  2. 【云原生&微服务二】SpringCloud之Ribbon自定义负载均衡策略(含Ribbon核心API)
  3. 【云原生&微服务三】SpringCloud之Ribbon是这样实现负载均衡的(源码剖析@LoadBalanced原理)
  4. 【云原生&微服务四】SpringCloud之Ribbon和Erueka集成的细节全在这了(源码剖析)
  5. 【微服务五】Ribbon随机负载均衡算法如何实现的

我们聊了以下问题:

  1. 为什么给RestTemplate类上加上了@LoadBalanced注解就可以使用Ribbon的负载均衡?
  2. SpringCloud是如何集成Ribbon的?
  3. Ribbon如何作用到RestTemplate上的?
  4. 如何获取到Ribbon的ILoadBalancer?
  5. ZoneAwareLoadBalancer(属于ribbon)如何与eureka整合,通过eureka client获取到对应注册表?
  6. ZoneAwareLoadBalancer如何持续从Eureka中获取最新的注册表信息?
  7. 如何根据负载均衡器ILoadBalancer从Eureka Client获取到的List<Server>中选出一个Server?
  8. Ribbon如何发送网络HTTP请求?
  9. Ribbon如何用IPing机制动态检查服务实例是否存活?
  10. Ribbon负载均衡策略之随机(RandomRule)实现方式;

本文继续讨论 轮询(RoundRobinRule)、重试(RetryRule)是如何实现的?

PS:Ribbon依赖Spring Cloud版本信息如下:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.3.7.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <!--整合spring cloud-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Hoxton.SR8</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <!--整合spring cloud alibaba-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>2.2.5.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

二、轮询算法 --> RoundRobinRule

我们知道Ribbon负载均衡算法体现在IRule的choose(Object key)方法中,而choose(Object key)方法中又会调用choose(ILoadBalancer lb, Object key)方法,所以我们只需要看各个IRule实现类的choose(ILoadBalancer lb, Object key)方法;
在这里插入图片描述
随机算法体现在RoundRobinRule#incrementAndGetModulo()方法:

private AtomicInteger nextServerCyclicCounter;

private int incrementAndGetModulo(int modulo) {
    // 死循环直到获取到一个索引下标
    for (;;) {
        // 获取当前AtomicInteger类型变量的原子值
        int current = nextServerCyclicCounter.get();
        // 当前原子值 + 1 然后对 服务实例个数取余
        int next = (current + 1) % modulo;
        // CAS修改AtomicInteger类型变量,CAS成功返回next,否则无限重试
        if (nextServerCyclicCounter.compareAndSet(current, next))
            return next;
    }
}
轮询算法很简单,重点在于通过AtomicInteger原子类型变量 + 死循环 CAS操作实现,每次返回 原子类型变量的当前值 + 1,因为原子类型变量可能超过服务实例数,所以每次对原子类型变量赋值时,都会对其和服务实例总数 做取余运算

三、重试算法 --> RetryRule

进入RetryRule的choose(ILoadBalancer lb, Object key)方法;
在这里插入图片描述

方法的核心逻辑:

  1. 首先记录开始要选择一个服务实例时的时间(即:开始请求时间为当前时间),和允许获取到服务实例的deadline,deadline为当前时间 + 500ms
  2. 接着使用RetryRule组合的RoundRobinRule轮询选择一个服务实例;
  3. 如果选择的服务实例为空并且当前时间还没到deadline 或 选择的服务实例不是活着的并且当前时间还没到deadline,则进行重试、重新获取一个服务实例;
  4. 重试之前会先启动一个延时(deadline-当前时间)执行的定时任务,其中负责到deadline时中断当前线程;
  5. 死循环(当前线程不是中断状态时),调用RoundRobin算法选择一个服务实例,如果这个服务实例是有效的 或 当前时间过了截止时间,则跳出循坏;并取消上面新建的延时执行的定时任务,返回当前实例;
  6. 如果服务实例不是活着的并且当前时间在截止时间之内,则调用Thread.yield(),让出线程资源,使当前线程 或 相同优先级的其他线程可以获取运行机会,也就是说 yield的线程有可能被线程调度程序再次选中执行。

所以:RetryRule在subRule.choose(String)获得无效的服务实例后,会一直重试,但重试次数取决于重试的deadline当前线程相同优先级的其他线程个数

相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
2月前
|
消息中间件 缓存 监控
优化微服务架构中的数据库访问:策略与最佳实践
在微服务架构中,数据库访问的效率直接影响到系统的性能和可扩展性。本文探讨了优化微服务架构中数据库访问的策略与最佳实践,包括数据分片、缓存策略、异步处理和服务间通信优化。通过具体的技术方案和实例分析,提供了一系列实用的建议,以帮助开发团队提升微服务系统的响应速度和稳定性。
|
2月前
|
运维 负载均衡 监控
深入探索微服务架构的核心要素与实践策略
在当今软件开发领域,微服务架构已成为构建灵活、可扩展企业级应用的首选模式。本文旨在剖析微服务架构的设计理念,通过实例阐述其核心组件如服务注册与发现、配置管理、熔断机制等如何协同工作,以提升系统的敏捷性和维护性。同时,探讨了在实践中应对分布式系统复杂性的最佳策略,包括负载均衡、服务监控和日志聚合等关键技术,旨在为后端开发者提供一套完整的微服务实施指南。
49 1
|
1天前
|
监控 安全 应用服务中间件
微服务架构下的API网关设计策略与实践####
本文深入探讨了在微服务架构下,API网关作为系统统一入口点的设计策略、实现细节及其在实际应用中的最佳实践。不同于传统的摘要概述,本部分将直接以一段精简的代码示例作为引子,展示一个基于NGINX的简单API网关配置片段,随后引出文章的核心内容,旨在通过具体实例激发读者兴趣,快速理解API网关在微服务架构中的关键作用及实现方式。 ```nginx server { listen 80; server_name api.example.com; location / { proxy_pass http://backend_service:5000;
|
10天前
|
监控 Cloud Native Java
云原生架构下微服务治理策略与实践####
【10月更文挑战第20天】 本文深入探讨了云原生环境下微服务架构的治理策略,通过分析当前技术趋势与挑战,提出了一系列高效、可扩展的微服务治理最佳实践方案。不同于传统摘要概述内容要点,本部分直接聚焦于治理核心——如何在动态多变的分布式系统中实现服务的自动发现、配置管理、流量控制及故障恢复,旨在为开发者提供一套系统性的方法论,助力企业在云端构建更加健壮、灵活的应用程序。 ####
55 10
|
6天前
|
监控 测试技术 API
确保微服务的API版本控制策略能够适应不断变化的业务需求
确保微服务的API版本控制策略能够适应不断变化的业务需求
|
6天前
|
监控 安全 Cloud Native
云原生安全:Istio在微服务架构中的安全策略与实践
【10月更文挑战第26天】随着云计算的发展,云原生架构成为企业数字化转型的关键。微服务作为其核心组件,虽具备灵活性和可扩展性,但也带来安全挑战。Istio作为开源服务网格,通过双向TLS加密、细粒度访问控制和强大的审计监控功能,有效保障微服务间的通信安全,成为云原生安全的重要工具。
20 2
|
10天前
|
监控 测试技术 API
如何确保微服务的API版本控制策略能够适应不断变化的业务需求?
如何确保微服务的API版本控制策略能够适应不断变化的业务需求?
|
17天前
|
负载均衡 监控 Cloud Native
云原生架构下的微服务治理策略与实践####
在数字化转型加速的今天,云原生技术以其高效、灵活、可扩展的特性成为企业IT架构转型的首选。本文深入探讨了云原生环境下微服务治理的策略与实践路径,旨在为读者提供一个系统性的微服务治理框架,涵盖从服务设计、部署、监控到运维的全生命周期管理,助力企业在云端构建更加稳定、高效的业务系统。 ####
|
20天前
|
负载均衡 算法 Java
腾讯面试:说说6大Nginx负载均衡?手写一下权重轮询策略?
尼恩,一位资深架构师,分享了关于负载均衡及其策略的深入解析,特别是基于权重的负载均衡策略。文章不仅介绍了Nginx的五大负载均衡策略,如轮询、加权轮询、IP哈希、最少连接数等,还提供了手写加权轮询算法的Java实现示例。通过这些内容,尼恩帮助读者系统化理解负载均衡技术,提升面试竞争力,实现技术上的“肌肉展示”。此外,他还提供了丰富的技术资料和面试指导,助力求职者在大厂面试中脱颖而出。
腾讯面试:说说6大Nginx负载均衡?手写一下权重轮询策略?
|
1月前
|
监控 测试技术 API
如何确保微服务的API版本控制策略能够适应不断变化的业务需求?
如何确保微服务的API版本控制策略能够适应不断变化的业务需求?