Dubbo-线程池调优实战分析

本文涉及的产品
性能测试 PTS,5000VUM额度
简介: Dubbo-线程池调优实战分析

Dubbo的线程池压测调优



\

dubbo的服务提供者端一共包含了两类线程池,一类叫做io线程池,还有一类叫做业务线程池,它们各自有着自己的分工,如下图所示


网络异常,图片无法展示
|


\

dubbo在服务提供方中有io线程池和业务线程池之分。可以通过调整相关的dispatcher参数来控制将请求处理交给不同的线程池处理。(下边列举工作中常用的几个参数:)


all:将请求全部交给业务线程池处理(这里面除了日常的消费者进行服务调用之外,还有关于服务的心跳校验,连接事件,断开服务,响应数据写回等)


execution:会将请求处理进行分离,心跳检测,连接等非业务核心模块交给io线程池处理,核心的业务调用接口则交由业务线程池处理。


假设说我们的dubbo接口只是一些简单的逻辑处理,例如说下方这类:


@Service(interfaceName = "msgService")
public class MsgServiceImpl implements MsgService {
    @Override
    public Boolean sendMsg(int id, String msg)  {
            System.out.println("msg is :"+msg);
            return true;
    }
}
复制代码


并没有过多的繁琐请求,并且我们手动设置线程池参数


dubbo.protocol.threadpool=fixed
dubbo.protocol.threads=10
dubbo.protocol.accepts=5
复制代码


当线程池满了的时候,服务会立马进入失败状态,此时如果需要给provider设置等待队列的话可以尝试使用queues参数进行设置。


dubbo.protocol.queues=100
复制代码


但是这个设置项虽然看似能够增大服务提供者的承载能力,却并不是特别建议开启,因为当我们的provider承载能力达到原先预期的限度时,通过请求堆积的方式继续请求指定的服务器并不是一个合理的方案,合理的做法应该是直接抛出线程池溢出异常,然后请求其他的服务提供者。


测试环境:


Mac笔记本,jvm:-xmx 256m -xms 256m
复制代码


接着通过使用jmeter进行压力测试,发现一秒钟调用100次(大于实际的业务线程数目下,线程池并没有发生溢出情况)。这是因为此时dubbo接口中的处理逻辑非常简单,这么点并发量并不会造成过大影响。(几乎所有请求都能正常抗住)


网络异常,图片无法展示
|


网络异常,图片无法展示
|


但是假设说我们的dubbo服务内部做了一定的业务处理,耗时较久,例如下方:


@Service(interfaceName = "msgService")
public class MsgServiceImpl implements MsgService {
    @Override
    public Boolean sendMsg(int id, String msg) throws InterruptedException {
            System.out.println("msg is :"+msg);
            Thread.sleep(500);
            return true;
    }
}
复制代码


此时再做压测,解果就会不一样了。


网络异常,图片无法展示
|


此时大部分的请求都会因为业务线程池中的数目有限出现堵塞,因此导致大量的rpc调用出现异常。可以在console窗口看到调用出现大量异常:


网络异常,图片无法展示
|


将jmeter的压测报告进行导出之后,可以看到调用成功率大大降低,


网络异常,图片无法展示
|


也仅仅只有10%左右的请求能够被成功处理,这样的服务假设进行了线程池参数优化之后又会如何呢?


1秒钟100个请求并发访问dubbo服务,此时业务线程池专心只处理服务调用的请求,并且最大线程数为100,服务端最大可接纳连接数也是100,按理来说应该所有请求都能正常处理


dubbo.protocol.threadpool=fixed
dubbo.protocol.dispatcher=execution
dubbo.protocol.threads=100
dubbo.protocol.accepts=100
复制代码


还是之前的压测参数,这回所有的请求都能正常返回。


网络异常,图片无法展示
|


ps:提出一个小问题,从测试报告中查看到平均接口的响应耗时为:502ms,也就是说其实dubbo接口的承载能力估计还能扩大个一倍左右,我又尝试加大了压测的力度,这次看看1秒钟190次请求会如何?(假设线程池100连接中,每个连接对请求的处理耗时大约为500ms,那么一秒时长大约能处理2个请求,但是考虑到一些额外的耗时可能达不到理想状态那么高,因此设置为每秒190次(190 <= 2*100)请求的压测)


网络异常,图片无法展示
|


但是此时发现请求的响应结果似乎并没有这么理想,这次请求响应的成功率大大降低了。


网络异常,图片无法展示
|


其实主要原因是当线程池满了的时候,服务会立马进入失败状态,而jmeter产生的压测线程数目并不是均匀的,可能190个线程的80%是在1s内的后0.5s中产生,这种情况下是会造成dubbo服务承载失败的。

相关实践学习
通过性能测试PTS对云服务器ECS进行规格选择与性能压测
本文为您介绍如何利用性能测试PTS对云服务器ECS进行规格选择与性能压测。
目录
相关文章
|
7天前
|
并行计算 安全 Java
Python GIL(全局解释器锁)机制对多线程性能影响的深度分析
在Python开发中,GIL(全局解释器锁)一直备受关注。本文基于CPython解释器,探讨GIL的技术本质及其对程序性能的影响。GIL确保同一时刻只有一个线程执行代码,以保护内存管理的安全性,但也限制了多线程并行计算的效率。文章分析了GIL的必要性、局限性,并介绍了多进程、异步编程等替代方案。尽管Python 3.13计划移除GIL,但该特性至少要到2028年才会默认禁用,因此理解GIL仍至关重要。
48 16
Python GIL(全局解释器锁)机制对多线程性能影响的深度分析
|
4月前
|
存储 NoSQL Redis
Redis 新版本引入多线程的利弊分析
【10月更文挑战第16天】Redis 新版本引入多线程是一个具有挑战性和机遇的改变。虽然多线程带来了一些潜在的问题和挑战,但也为 Redis 提供了进一步提升性能和扩展能力的可能性。在实际应用中,我们需要根据具体的需求和场景,综合评估多线程的利弊,谨慎地选择和使用 Redis 的新版本。同时,Redis 开发者也需要不断努力,优化和完善多线程机制,以提供更加稳定、高效和可靠的 Redis 服务。
105 1
|
4月前
线程CPU异常定位分析
【10月更文挑战第3天】 开发过程中会出现一些CPU异常升高的问题,想要定位到具体的位置就需要一系列的分析,记录一些分析手段。
104 0
|
2月前
|
并行计算 算法 安全
面试必问的多线程优化技巧与实战
多线程编程是现代软件开发中不可或缺的一部分,特别是在处理高并发场景和优化程序性能时。作为Java开发者,掌握多线程优化技巧不仅能够提升程序的执行效率,还能在面试中脱颖而出。本文将从多线程基础、线程与进程的区别、多线程的优势出发,深入探讨如何避免死锁与竞态条件、线程间的通信机制、线程池的使用优势、线程优化算法与数据结构的选择,以及硬件加速技术。通过多个Java示例,我们将揭示这些技术的底层原理与实现方法。
105 3
|
2月前
|
调度 开发者
核心概念解析:进程与线程的对比分析
在操作系统和计算机编程领域,进程和线程是两个基本而核心的概念。它们是程序执行和资源管理的基础,但它们之间存在显著的差异。本文将深入探讨进程与线程的区别,并分析它们在现代软件开发中的应用和重要性。
78 4
|
3月前
|
安全 Java 开发者
Java 多线程并发控制:深入理解与实战应用
《Java多线程并发控制:深入理解与实战应用》一书详细解析了Java多线程编程的核心概念、并发控制技术及其实战技巧,适合Java开发者深入学习和实践参考。
90 7
|
3月前
|
存储 安全 Java
Java多线程编程中的并发容器:深入解析与实战应用####
在本文中,我们将探讨Java多线程编程中的一个核心话题——并发容器。不同于传统单一线程环境下的数据结构,并发容器专为多线程场景设计,确保数据访问的线程安全性和高效性。我们将从基础概念出发,逐步深入到`java.util.concurrent`包下的核心并发容器实现,如`ConcurrentHashMap`、`CopyOnWriteArrayList`以及`BlockingQueue`等,通过实例代码演示其使用方法,并分析它们背后的设计原理与适用场景。无论你是Java并发编程的初学者还是希望深化理解的开发者,本文都将为你提供有价值的见解与实践指导。 --- ####
|
3月前
|
监控 Java 开发者
Java线程池调优指南###
本文深入探讨了Java线程池的工作原理与调优策略,旨在帮助开发者理解线程池的核心参数及其对应用性能的影响。通过实例分析,揭示如何根据具体业务场景合理配置线程池,以实现资源高效利用和系统稳定性的平衡。 ###
|
4月前
|
监控 Java Linux
Java 性能调优:调整 GC 线程以获得最佳结果
Java 性能调优:调整 GC 线程以获得最佳结果
107 11
|
4月前
|
数据挖掘 程序员 调度
探索Python的并发编程:线程与进程的实战应用
【10月更文挑战第4天】 本文深入探讨了Python中实现并发编程的两种主要方式——线程和进程,通过对比分析它们的特点、适用场景以及在实际编程中的应用,为读者提供清晰的指导。同时,文章还介绍了一些高级并发模型如协程,并给出了性能优化的建议。
57 3