当Dubbo遇到高并发:探究流量控制解决方案

系列文章目录

面试Dubbo ,却问我和Springcloud有什么区别?
超简单,手把手教你搭建Dubbo工程(内附源码)
【收藏向】从用法到源码,一篇文章让你精通Dubbo的SPI机制
Dubbo最核心功能——服务暴露的配置、使用及原理
并不简单的代理,Dubbo是如何做服务引用的
不满足于RPC,详解Dubbo的服务调用链路
从理论到实践,必须了解的部分Dubbo配置



在这里插入图片描述

在当今互联网时代,随着用户量的不断增长和业务复杂性的提升,高并发成为了很多系统面临的挑战。Dubbo作为一种优秀的分布式服务框架,在大规模高并发场景下也面临着一系列的挑战,其中最突出的,就是大量调用带来的流量问题。这次我就和大家一起探讨下Dubbo在高并发情况下的问题,并针对性地介绍流量控制解决方案,帮助大家更好地应对高并发场景下的挑战

📕作者简介:战斧,多年开发及管理经验,爱好广泛,致力于创作更多高质量内容
📗本文收录于 Dubbo专栏,有需要者,可直接订阅专栏实时获取更新
📘高质量专栏 RabbitMQ、Spring全家桶 等仍在更新,欢迎指导
📙Zookeeper Redis kafka docker netty等诸多框架,以及架构与分布式专题即将上线,敬请期待


一、与Dubbo有相关的高并发问题

1. 资源耗尽

高并发情况下,Dubbo所占用的资源会大幅上升,包括线程池、内存、CPU等。当资源耗尽时,系统性能会急剧下降,甚至导致系统崩溃。并且因为Dubbo使用的长连接通信,高并发下会导致连接状态过多,可能会导致网络堵塞、连接耗尽等问题

2. 服务雪崩

服务雪崩是指当某个服务出现故障或响应过慢时,请求会在服务之间传递,导致所有相关服务都不可用的现象。在高并发情况下,一旦出现服务雪崩,整个系统的可用性将受到严重影响。
在这里插入图片描述
如图,故障应用的影响范围,会逆着调用方向进行扩散,导致更大面积的故障。

二、控制思路

其实我们分析Dubbo在高并发情况下的问题,随着并发数的增多,前者(资源占用)其实是不可避免的,解决策略无非是硬件升级或性能优化来进行缓解。我们真正关注的,其实是:

  1. 如何控制单台机器或单个服务的流量,避免负载过重,过长响应时间甚至宕机?
  2. 如果真的出现响应缓慢甚至宕机,如何避免故障扩大化,防止服务雪崩?

单机流量控制 ,思路主要就是分流、限流和错峰,其中限流也可以分为入口请求限流,和服务自身的保护式限流。同时也要注意,流量不仅来源于入口,也应该避免架构体系自身产生过多内部请求。
避免服务雪崩,主要考虑单机架构层面,单机层面针对某些服务拆分不够细的工程,一个服务过饱和,不应该影响该机器的其他服务。架构层面:一台机器的宕机,主要依赖于故障转移,及时的熔断降级进行处理,尽量不影响其他机器

三、控制方案

1. 限流策略

限流是最常见也是最有效的流量控制手段之一。通过限制每个服务的最大并发请求量,可以有效防止系统被过多的请求压垮。在Dubbo中,其实对于服务提供者有着现成的限流保护:TpsLimitFilter

@Activate(group = CommonConstants.PROVIDER, value = TPS_LIMIT_RATE_KEY)
public class TpsLimitFilter implements Filter {
    private final TPSLimiter tpsLimiter = new DefaultTPSLimiter();
    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        if (!tpsLimiter.isAllowable(invoker.getUrl(), invocation)) {
            throw new RpcException(
                    "Failed to invoke service " +
                            invoker.getInterface().getName() +
                            "." +
                            invocation.getMethodName() +
                            " because exceed max service tps.");
        }
        return invoker.invoke(invocation);
    }
}

但官方可能觉得这种程度的限流并不够理想,因此没有使用它,使得想真正启用该拦截器还要开发者手动做不少处理。因此我们也并不推荐这种做法。
与之对比的是,官方目前大力推广的都是借助第三方组件如Sentinel实现限流策略。Sentinel 提供了与 Dubbo 适配的模块 – Sentinel Dubbo Adapter,包括针对服务提供方的过滤器和服务消费方的过滤器(Filter)。使用时我们只需引入以下模块(dubbo3.0.5以上)

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-apache-dubbo3-adapter</artifactId>
    <version>x1.8.6</version>
</dependency>

引入此依赖后,Dubbo 的服务接口和方法(包括调用端和服务端)就会成为 Sentinel 中的资源,在配置了规则后就可以自动享受到 Sentinel 的防护能力。

2. 服务降级

服务降级是在系统遇到高并发或资源耗尽的情况下,暂时屏蔽一些非核心或可选功能,保证系统的核心功能依然可用。Dubbo支持在服务提供方进行服务降级,可以通过设置降级策略来应对高并发时的情况。在Dubbo里,我们可以使用Mock功能来实现降级,即通过配置消费端的mock参数,设定服务降级策略
我们还以以前的Demo为例子,写一个Mock:

public class DemoServiceMock implements DemoService {
    @Override
    public String sayHello(String name) {
        return "出现故障,mock上任";
    }
}

然后在引用的位置加上 mock 参数为 true,当然mock的用法有很多种,你也可以直接写实现类名。
在这里插入图片描述

然后将服务提供者进行线程睡眠处理
在这里插入图片描述

此时,将触发Mock的执行
在这里插入图片描述

3. 超时重试

对于一些耗时较长的服务调用,设置合理的超时时间是必要的。超时控制可以防止请求在服务提供方占用过多资源,从而保护系统的稳定性。在Dubbo中,我们可以通过配置超时时间来控制服务的调用时间。
在这里插入图片描述
有记忆好的朋友,应该还记得 【问题处理】—— 一次内存溢出(OutOfMemoryError)实战排查 这个问题,其中很大原因就是调用下游系统,下游系统卡死,但超时设置时间过长,导致资源占用太多。所以保持较小的超时时间可以避免故障扩大。
重试则是指消费端在调用失败后的重试次数,在高并发下,这个值可以设置的小一些,甚至可以不进行重试

4. 故障转移

在高并发情况下,服务之间的调用可能会因网络波动或服务不可用而失败。Dubbo提供了多种集群容错策略,如快速失败、失败重试、失败安全等,可以根据具体情况选择合适的策略,保障服务的稳定性。
在这里插入图片描述
关于集群容错,现在内置的几种方案,我们此处并不细说,主要是根据应用场景来进行选择。

5. 负载均衡

配合着限流的,还应当有分流,而负载均衡就起到了分流的作用,我们在Dubbo中可以设置多种负载均衡模式:
在这里插入图片描述
我们可以进行全局配置,比如

<!-- 全局负载均衡策略 -->
<dubbo:consumer loadbalance="random" />

也可以进行服务接口级别的配置,比如

@Service(interfaceClass = XxxService.class, loadbalance = "leastactive")
public class XxxServiceImpl implements XxxService {
    //...
}

其多种均衡策略,leastactive - “最少活跃调用数负载均衡” 是比较适合在高并发场景下选用的,,即当前活跃数(active,即指某个服务提供者正在处理请求的数量)最小的那个服务提供者,如果活跃数相同,则随机选择一个。比如,当前有3个服务提供者,其活跃数分别为:2、3、4,那么就会选择活跃数为2的服务提供者。当第一个服务提供者的活跃数增加到3时,那么最少活跃调用数的服务提供者就变成了第一个服务提供者

6. 线程池隔离

当某一块业务访问量大增,往往会伴随着资源占用的急剧增加,但是我们并不希望应用整个宕机,此时就要用到线程池隔离,线程池隔离是一种将请求任务与线程池分离的技术,我们在Dubbo里可以这么使用executes来为指定服务建立定长的线程池

@Service
@DubboService(interfaceClass = XxxService.class, executes = 10)
public class XxxServiceImpl implements XxxService {
    // 服务实现代码
}

这将为该服务创建一个固定大小为10的线程池,供服务消费者调用该服务时使用。这样当同时有11个请求到来时,第11个请求只能等到或被拒,事实上形成了限流,具有类似效果的参数还有 actives

7. 异步削峰

我们其实在讲rabbitMQ的时候,就提到过异步的好处,其中之一就是可以削峰。同样的Dubbo也能使用 async 进行异步调用,来避免瞬时的大流量造成的服务故障。更具体的讲,这种场景下有三个好处:
在这里插入图片描述

  1. 减少响应时间:在高并发场景下,同步调用会阻塞线程,导致响应时间变长。而异步调用可以让线程立即返回,不用等待响应,从而缩短响应时间。
  2. 提高容错能力:在同步调用中,如果某个调用出现异常,那么整个调用链都会被打断,从而影响到其他调用的正常执行。而异步调用会把调用拆分成多个独立的任务,每个任务独立执行,如果其中某个任务出现异常,不会影响其他任务的执行,从而提高了容错能力。
  3. 提高吞吐量:在高并发场景下,同步调用可能会因为线程阻塞导致线程池资源耗尽,从而影响系统的吞吐量。异步调用可以将请求提交到异步线程池中执行,从而释放主线程,提高了系统的吞吐量。

而我们的设置也是可以分为全局设置,和服务接口级别。其中全局配置如下(不建议):

<dubbo:consumer async="true" />
<dubbo:provider async="true" />

单个服务配置如下

@DubboReference(async = true)
private DemoService demoService;

四、结论

高并发是Dubbo应用需要面对的一个持续挑战。通过合理配置流量控制方案,包括限流策略、服务降级、超时控制和集群容错等操作,我们可以有效地保护系统免受高并发压力带来的影响。同时,需要注意不同业务场景可能需要不同的流量控制策略,因此我们需要根据实际情况进行调优和监控。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/116278.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

VSCode 设置平滑光标

1.点击左下角的设置按钮&#xff0c;再点击设置 2.点击文本编辑器&#xff0c;点击光标&#xff0c;勾选控制是否启用平滑插入动画。 3.随便打开一个文件&#xff0c;上下左右移动光标时&#xff0c;会发现非常的流畅。 原创作者&#xff1a;吴小糖 创作时间&#xff1a;2023…

华为RS设备状态及接口配置命令

1、查看硬件信息 ①查看序列号 查看整机序列号 display esn display sn ②、查看功率 电源功率 display power 查看光模块功率 display transceiver interface gigabitethernet 1/0/0 verbose ③、查看风扇 display fan ④、查看温度 display temperature all ⑤、查看硬…

安全防御——二、ENSP防火墙实验学习

安全防御 一、防火墙接口以及模式配置1、untrust区域2、trust区域3、DMZ区域4、接口对演示 二、防火墙的策略1、定义与原理2、防火墙策略配置2.1 安全策略工作流程2.2 查询和创建会话 3、实验策略配置3.1 trust-to-untrust3.2 trust-to-dmz3.3 untrust-to-dmz 三、防火墙的区域…

ssh登录界面变成vim提示,进不去系统

是ubuntu系统 使用远程连接root&#xff0c;进去后发现界面变成vim编辑器的介绍界面了 使用普通用户登录 查询用户的登录shell是不是有问题 sudo vim /etc/passwd 发现用户shell变成了vim编辑器 修改为/bin/bash就可以正常登录了 重新登录测试就正常了

【Linux】 man命令使用

介绍 man命令是Linux下最核心的命令之一。而man命令也并不是英文单词“man”的意思&#xff0c;它是单词manual的缩写&#xff0c;即使用手册的意思。 man命令会列出一份完整的说明。 其内容包括命令语法、各选项的意义及相关命令 。更为强大的是&#xff0c;不仅可以查看Lin…

【计算机网络实验/wireshark】tcp建立和释放

wireshark开始捕获后&#xff0c;浏览器打开xg.swjtu.edu.cn&#xff0c;网页传输完成后&#xff0c;关闭浏览器&#xff0c;然后停止报文捕获。 若捕获不到dns报文&#xff0c;先运行ipconfig/flushdns命令清空dns缓存 DNS报文 设置了筛选条件&#xff1a;dns 查询报文目的…

openpnp - 74路西门子飞达控制板(主控板STM32_NUCLEO-144)实现

文章目录 openpnp - 74路西门子飞达控制板(主控板STM32_NUCLEO-144)实现概述飞达控制底板硬件电路程序的修改END openpnp - 74路西门子飞达控制板(主控板STM32_NUCLEO-144)实现 概述 现在调试自己的openpnp设备, 在收尾, 将飞达控制板弄好, 能正常控制设备飞达安装平台上装满…

go语言 | grpc原理介绍(二)

gRPC gRPC 是一个高性能、通用的开源 RPC 框架&#xff0c;其由 Google 2015 年主要面向移动应用开发并基于 HTTP/2 协议标准而设计&#xff0c;基于 ProtoBuf 序列化协议开发&#xff0c;且支持众多开发语言。 由于是开源框架&#xff0c;通信的双方可以进行二次开发&#x…

前端基础之CSS

目录 一、CSS介绍 CSS语法 CSS注释 CSS的几种引入方式 二、CSS选择器 基本选择器 组合选择器 属性选择器 分组和嵌套选择器 伪类选择器 伪元素选择器 选择器的优先级 三、CSS属性相关 宽和高 字体属性 文字属性 背景属性 边框 border-radius display属性 …

与AI对话的艺术:如何优化Prompt以获得更好的响应反馈

前言 在当今数字化时代&#xff0c;人工智能系统已经成为我们生活的一部分。我们可以在智能助手、聊天机器人、搜索引擎等各种场合与AI进行对话。然而&#xff0c;要获得有益的回应&#xff0c;我们需要学会与AI进行有效的沟通&#xff0c;这就涉及到如何编写好的Prompt。 与…

docker 安装 minio (单体架构)

文字归档&#xff1a;https://www.yuque.com/u27599042/coding_star/qcsmgom7basm6y64 查询 minio 镜像 docker search minio拉取镜像 docker pull minio/minio创建启动 minio 容器 用户名长度至少为 3&#xff0c;密码长度至少为 8 docker run \ -p 9000:9000 \ -p 9090:909…

轻量封装WebGPU渲染系统示例<13>- 屏幕空间后处理效果(源码)

当前示例源码github地址: https://github.com/vilyLei/voxwebgpu/blob/main/src/voxgpu/sample/ScreenPostEffect.ts 此示例渲染系统实现的特性: 1. 用户态与系统态隔离。 细节请见&#xff1a;引擎系统设计思路 - 用户态与系统态隔离-CSDN博客 2. 高频调用与低频调用隔离。…

C++基础——对于C语言缺点的补充(1)

目录 1.命名空间&#xff1a; 1.1 为什么要引入命名空间&#xff1a; 1.2 命名空间的作用&#xff1a; 1.3 如何访问命名空间内的变量&#xff1a; 1.4 命名空间的嵌套&#xff1a; 1.5 不同文件下同名命名空间的合并&#xff1a; 1.6 命名空间的展开&#xff1a; 2. C…

canal+es+kibana+springboot

1、环境准备 服务器&#xff1a;Centos7 Jdk版本&#xff1a;1.8 Mysql版本&#xff1a;5.7.44 Canal版本&#xff1a;1.17 Es版本&#xff1a;7.12.1 kibana版本&#xff1a;7.12.1 软件包下载地址&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1jRpCJP0-hr9aI…

openGauss学习笔记-114 openGauss 数据库管理-设置安全策略-设置帐号有效期

文章目录 openGauss学习笔记-114 openGauss 数据库管理-设置安全策略-设置帐号有效期114.1 注意事项114.2 操作步骤 openGauss学习笔记-114 openGauss 数据库管理-设置安全策略-设置帐号有效期 114.1 注意事项 创建新用户时&#xff0c;需要限制用户的操作期限&#xff08;有…

antv/g6元素之combo

介绍 在 G6 中&#xff0c;“Combo” 是一种特殊的元素&#xff0c;用于组合和展示多个节点元素的一种方式。它通常用于表示一个组或子图&#xff0c;将多个相关节点组织在一起&#xff0c;并在图形中以单一的形状显示。 属性 type&#xff1a;Combo 的类型&#xff0c;通常是…

【Redis】Redis常用命令-getsetkeysexistsexpirettltype

文章目录 读取文档注意事项set命令get命令全局/通用命令KEYSEXISTSDELEXPIRETTLTYPE 读取文档注意事项 官方文档链接&#xff1a;https://redis.io/ 注意&#xff1a;redis的命令不区分大小写 在redis文档给出的语法格式说明&#xff1a; []&#xff1a;相当于一个独立的单元&a…

面试—如何介绍项目中的多级缓存?

项目中使用的多级缓存也就是 分布式缓存 Redis 本地缓存 Caffeine&#xff0c;那么令 Caffeine 作为一级缓存&#xff0c;Redis 作为二级缓存&#xff0c;在项目中通过记录数据的访问次数&#xff0c;将热点数据放在 本地缓存&#xff0c;将非热点数据放在 Redis缓存 中&#…

详解RSA加密算法 | Java模拟实现RSA算法

目录 一.什么是RSA算法 二.RSA算法的算法原理 算法描述 三.RSA算法安全性 四.RSA算法的速度 五.用java实现RSA算法 一.什么是RSA算法 1976年&#xff0c;Diffie和Hellman在文章“密码学新方向&#xff08;New Direction in Cryptography&#xff09;”中首次提出了公开…

FSB逮捕为乌克兰网络部队工作的俄罗斯黑客

导语 近日&#xff0c;俄罗斯联邦安全局&#xff08;FSB&#xff09;逮捕了两名涉嫌协助乌克兰网络部队对俄罗斯重要基础设施目标进行网络攻击的个人。这起事件引起了广泛关注&#xff0c;涉及到了网络安全和国际关系等多个领域。本文将为您详细介绍这一事件的背景和最新进展。…