谈谈JSF业务线程池的大小配置
1.简介
JSF业务线程池使用JDK的线程池技术,缺省情况下采用Cached模式(核心线程数20,最大线程数200)。此外,还提供了Fixed固定线程大小的模式,两种模式均可设置请求队列大小。
本文旨在通过一个简化场景(“单服务应用”)下的负载测试,为“JSF业务线程池大小配置”提供基准测试结果,并形成一些普遍适用的结论。
本文的目标读者包括需要合理配置JSF线程大小的压测工程师、开发部署运维工程师以及架构师。本文不涉及JSF服务端的其他配置项,也不针对“复合服务应用”的合理配置进行探讨。你可以利用本文提供的结论,作为设计压测用例或评估业务线程池大小的基本方法的参考,以便在实践中合理配置JSF业务线程池大小。需要注意的是,JSF业务线程池大小的合理配置应该基于高保真的负载测试结果。
“单服务应用”指应用仅包含一个提供接口,且接口中仅有一个方法。
“复合服务应用”则指应用包含多个提供接口或一个接口中含有多个方法。
2.测试用例说明
本次基准测试选取了USF3.0权限系统,将其定制化为一个单一的服务提供者,仅对该提供者的一个方法进行了测试,因此可以看作是一个“单服务应用”。测试中将CPU作为基准测试的核心资源,并考虑到JVM垃圾收集器的影响,采用了简单的测试数据以保证服务每次调用的一致性,并确保YGC具有规律性(即固定调用量会导致一次30+ms的YGC),无FGC的影响。
测试用例的设计中,所有依赖的服务资源都无限制,以确保测试过程中服务的可用率达到100%。我们的关键性能指标是TP99,即服务响应时长的99%必须小于10ms。
为了测试不同线程池模式下的性能表现,我们使用了JSF线程池的Cached和Fixed两种模式,并针对每种模式进行了多组测试,以得出在满足TP99<10ms的前提下,系统最大的负载情况。
测试应用:USF3.0权限系统(定制化处理)
测试服务:com.jd.susf.service.api.SusfPermissionService#findUserInfo,根据用户信息从Redis中查询一条数据返回的服务。
硬件配置:单台4C 8G
测试方法:在Forcebot系统采用了阶梯发压的方式对JSF业务线程池在Cached和Fixed模式下进行了系统负载测试
拟定SLA要求:服务响应时长的TP99<10ms
注:我们对USF3.0权限系统进行了定制,调整了服务提供方的配置数据,仅保留了 com.jd.susf.service.api.SusfPermissionService。
3.测试结果及分析
3.1.cached线程池的系统负载
图:JSF默认线程池(cached, threads=200)在不同并发用户数(1-200)下的系统负载图
| 并发用户数 | TP99 | 吞吐量TPS | CPU利用率(%) |
|---|---|---|---|
| 1~23 | <8ms | 线性增长 | 线性增长 |
| 24 | 8ms | 6553 | 99.62 |
| 25 | 11ms | 6607 | 99.83 |
| 26~79 | 迅速增长 | 缓慢增长 | 99+ |
| 80 | 74ms | 6928 | 99.82 |
| 81~199 | 缓慢增加 | 缓慢下降 | 99.82 |
| 200 | 99ms | 6230 | 99.94 |
小结:默认的JSF线程池配置存在很大的风险。系统最大可支持24个并发,超过24个并发SLA就无法满足。
3.2 fixed线程池(队列)的系统负载
图:JSF固定线程池(fixed+队列)在不同并发用户数(1-50)下的系统负载图
| JSF业务线程数 | 可支持的最大并发用户数 | TP值(50/90/99/999) | 吞吐量(TPS) | CPU最大利用率(%) |
|---|---|---|---|---|
| 4 | 11 | 7/8/10/18 | 1531 | 27.67 |
| 8 | 25 | 8/8/10/18 | 3113 | 46.45 |
| 16 | 50 | 8/8/10/21 | 6228 | 87.97 |
| 20 | 23 | 3/4/10/15 | 6409 | 99.92 |
| 24 | 22 | 3/4/7/15 | 6178 | 99.86 |
| 25 | 22 | 3/4/6/15 | 6182 | 98.83 |
表:JSF固定业务线程池(fixed+队列)在满足TP99<10ms的系统最大负载(最大并发用户数)
小结:
① 在fixed线程模式下,CPU的利用率存在使用上限。
② 队列的使用可以有效增加系统对并发量的支持,同时也会带来吞吐量的提升。然而,由于任务在队列中等待,服务的响应时间会出现“水涨船高”的现象,存在一定风险。
3.3 fixed线程池的系统负载
图:JSF固定线程池(fixed)模式下,系统最大并发用户数时的系统负载
| JSF业务线程数 | 并发用户数 | TP99 | 吞吐量(TPS) | CPU最大利用率(%) |
|---|---|---|---|---|
| 4 | 4 | 5 | 1063 | 20.26 |
| 8 | 8 | 5 | 2216 | 36.62 |
| 16 | 16 | 6 | 4262 | 68.56 |
| 20 | 20 | 5 | 5550 | 86.22 |
| 24 | 24 | 8 | 6711 | 99.62 |
| 25 | 25 | 16 | 6644 | 98.77 |
| 26 | 26 | 19 | 6744 | 99.93 |
小结:综合固定线程池(fixed)的性能表现,需要设置一个合理的线程数大小来平衡CPU资源的充分利用和满足SLA的需求,线程数过小会导致CPU资源浪费,线程数过大则无法满足SLA
4.结论
根据测试结果和数据分析,我们得出以下结论:
- JSF线程池的默认配置在并发量高的场景下存在风险:所有线上生产环境中的JSF服务所在的服务器,很少有能够在200个线程的情况下还能够满足SLA的。最大200个线程的线程池配置,将服务器置于“并发量高的场景下被压垮”的风险中。线程池大小的合理配置应该来自高保真的负载测试。
- 足量的线程数才能保证资源(CPU)的利用率:业务型的服务通常都存在一定的IO操作(网络,磁盘等),线程执行过程中会发生等待,CPU利用率不高,需要增加并发的线程数量,让更多的线程参与CPU的分配,才能提高CPU的利用率。服务中IO操作越多,等待时长越长,需要的并发线程就越多。对于有IO操作的业务型服务,负载测试的线程数可以从2N(N是服务器的CPU核数)开始。
- 过多的线程数只会降低系统的SLA:当线程数已能100%利用CPU后,增加线程数,线程就无法获取足够的CPU分配,这样服务的响应时间就会增大。在一定范围内,TP99还可能满足SLA的要求,系统的吞吐量也会有少量的增加。再持续增加线程数,TP99就无法满足系统的要求,系统的吞吐量也会开始下降。
- 固定的线程数可以保护系统需要承担的负载能力:固定线程数可以保证系统对CPU的利用率限定在一定的负载范围内,保护系统稳定运行,保证响应时间TP99,但也限定了系统的并发能力。合理设置队列大小可以增加系统的并发度,也不会影响系统TP99,但会整体拉高服务的响应时间,出现不稳定性的变化,存在风险。
- 让CPU100%的高负载运行:通常服务对外的SLA承诺通常高于服务真实的性能,这是因为我们考虑了基础设施及依赖服务的不稳定性。因此,即使CPU已经达到了100%,我们仍然可以增加一定数量的线程数,而不会影响对外的响应时间TP99的承诺。这样可以提高系统的并发能力。虽然系统可以在高负载下运行,但我们需要进一步进行稳定性测试,以提高系统的可靠性。
综上所述,线程池大小的合理配置需要结合业务需求和系统资源情况进行评估和测试,并预留合理的buffer空间,以保证系统稳定运行和满足用户的SLA。
5.附录
附录一:统计指标及术语说明
并发用户数:同时发起请求的用户数。
TP值(50/90/99/999):客户端的TP值,单位ms,数据来源于Forcebot。
吞吐量TPS:数据来源于Forcebot。
CPU利用率(%):数据来源于PFinder。
JSF业务线程数:JSF业务线程池的线程数,如:<jsf:server id="jsf" protocol="jsf" threadpool="fixed" threads="16" />
fixed/cached:JSF业务线程池的线程池类型,如:<jsf:server id="jsf" protocol="jsf" threadpool="fixed" threads="200"/>
作者:京东物流 刘江波
来源:京东云开发者社区 自猿其说Tech 转载请注明来源
谈谈JSF业务线程池的大小配置的更多相关文章
- 到底如何设置 Java 线程池的大小?
来源:ifeve.com/how-to-calculate-threadpool-size/ 在我们日常业务开发过程中,或多或少都会用到并发的功能.那么在用到并发功能的过程中,就肯定会碰到下面这个问题 ...
- java多线程、线程池及Spring配置线程池详解
1.java中为什么要使用多线程使用多线程,可以把一些大任务分解成多个小任务来执行,多个小任务之间互不影像,同时进行,这样,充分利用了cpu资源.2.java中简单的实现多线程的方式 继承Thread ...
- Tomcat线程池与NIO配置
每个web客户端请求对于服务器端来说就一个单独的线程,客户端的请求数量增多将会导致线程数就上去了,CPU就忙着跟线程切换. 而NIO则是使用单线程(单个CPU)或者只使用少量的多线程(多CPU)来接受 ...
- 简单RPC框架-业务线程池
*:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...
- spring定时任务.线程池,自定义多线程配置
定时任务及多线程配置xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=" ...
- 谈谈Java的线程池设计
在实际项目中,如果因为想异步执行暂时性的任务而不断创建线程是很浪费资源的事情(当一个任务执行完后,线程也没用了).这种情况下,最好是将任务提交给线程池执行. 所谓池,就是将管理某一种资源,对资源进行复 ...
- 基于Netty的RPC架构学习笔记(十二):借助spring实现业务分离、聊天室小项目、netty3和4、5的不同、业务线程池以及消息串行化
文章目录 借助spring实现业务分离(
- 【mq读书笔记】客户端处理消息(回调提交到异步业务线程池,pullRequest重新入队)
看一下客户端收到消息后的处理: MQClientAPIImpl#processPullResponse private PullResult processPullResponse( final Re ...
- Java线程池实现原理及其在美团业务中的实践
本文转载自Java线程池实现原理及其在美团业务中的实践 导语 随着计算机行业的飞速发展,摩尔定律逐渐失效,多核CPU成为主流.使用多线程并行计算逐渐成为开发人员提升服务器性能的基本武器.J.U.C提供 ...
- SpringBoot异步使用@Async原理及线程池配置
前言 在实际项目开发中很多业务场景需要使用异步去完成,比如消息通知,日志记录,等非常常用的都可以通过异步去执行,提高效率,那么在Spring框架中应该如何去使用异步呢 使用步骤 完成异步操作一般有两种 ...
随机推荐
- 最详细的Git命令大全
Git常用命令及方法大全 下面是我整理的常用 Git 命令清单.几个专用名词的译名如下. Workspace:工作区 Index / Stage:暂存区 Repository:仓库区(或本地仓库) R ...
- 代码随想录算法训练营Day24 回溯算法|216.组合总和III 17.电话号码的字母组合
代码随想录算法训练营 216.组合总和III 题目链接:216.组合总和III 找出所有相加之和为 n 的 k 个数的组合.组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字. 说 ...
- python---序列化小结
python 序列化 1 什么叫序列化 在我们存储数据或网络传输数据时候,需要多我们对象进行处理,把对象处理成方便储存和网络传输的数据格式,这个过程叫做序列化 2 对象序列化有三种方式; 2.1 pi ...
- tryhackem_wonderland
涉及,解密,扫描,横向移动,纵向移动 仙境 掉进兔子洞,进入仙境. 获得shell 解法一: 目录扫描 ffuf -u http://10.10.134.189/FUZZ -w /usr/share/ ...
- 万字长文讲透 RocketMQ 4.X 消费逻辑
RocketMQ 是笔者非常喜欢的消息队列,4.9.X 版本是目前使用最广泛的版本,但它的消费逻辑相对较重,很多同学学习起来没有头绪. 这篇文章,笔者梳理了 RocketMQ 的消费逻辑,希望对大家有 ...
- 一定要看的前端codeReview规范指南
一.前言 针对目录结构.CSS规范.JavaScript规范.Vue规范 可参照官方给出的 风格指南 这里主要总结业务开发中常遇到的代码问题和实践,帮助大家后续各自做好codeReview,一些你遇到 ...
- 【LeetCode】Find Pivot Index #724 Rust Solution
给定一个整数类型的数组 nums,请编写一个能够返回数组 "中心索引" 的方法.我们是这样定义数组 中心索引 的:数组中心索引的左侧所有元素相加的和等于右侧所有元素相加的和.如果数 ...
- STM32低功耗配置
一.相关介绍 1.1 STM32下的电源管理 电源框图 电源标号说明 电压调节器 复位后调节器总是使能.以3种不同的模式工作. 运转模式:调节器以正常功耗模式提供1.8V电源(内核,内存和外设). 停 ...
- CKS 考试题整理 (13)-使用 sysdig 检查容器里里的异常进程
Task 使用运行时检测工具来检测 Pod tomcat 单个容器中频发生成和执行的异常进程 有两种工具可供使用: sysdig falco 注: 这些工具只预装在cluster的工作节点,不在 ma ...
- C++面试八股文:std::string是如何实现的?
某日二师兄参加XXX科技公司的C++工程师开发岗位第18面: 面试官:std::string用过吧? 二师兄:当然用过(废话,C++程序员就没有没用过std::string的). 面试官:std::s ...