线程池中线程数量与队列大小参数的如何设置实践-基于QPS的计算公式

目录

概要

传统方式?

线程池理解?

基于QPS的设置思路?

总结?


概要

线程池是个既靠谱但又陌生的家伙, 像管家一样, 会踏踏实实的把你交代的任务完成, 但很死板, 没有自动安排人的能力, 需要你给它配好人手(线程实例)和承载容量(队列大小), 这些参数关系影响业务服务整体的吞吐量与并发能力表现, 所以在日常工作根据业务情况进行自定义配置很重要, 但线程池的参数并不好配置, 一方面线程池本身运作机制的理解需要一定的门槛, 另一方面参数调整需要分析实际业务场景, 强依赖工程师的个人经验. 

传统方式?

 线程数完全核数决定, 通常核心线程数是核数或核数*2, 最大线程数为核数*2或核数*4, 讲究一点的会根据业务偏向IO型或CPU型做些调整, 公式如下: 

线程数 = CPU核心数 * (1 + 等待时间/CPU计算时间)

  • 等待时间越长代表偏向于IO型, 为避免进入IO阻塞状态时cpu空闲下来, 可以多设置些线程, 尽可能提升CPU利用率.
  • 计算时间越长代表偏向CPU型, 代表对CPU利用率已经足够的高了, 线程数就设置少些, 接近核数即可.

但问题在于等待时间和CPU计算时间难测量与得到, 且波动很大,可以作为优化方向指导, 但实际难以应用, 需要靠感觉和经验. 线程数设置过多不仅占用系统资源, 同时频繁的线程上下文切换也会带来性能的损耗, 而线程数设置过少发挥不出来处理器的并发能力.

 队列方面, 会直接使用阻塞队列, 长度呢? 粗暴设置大点, 核数*64或128, 这种设置方式尤其是队列的设置过大会导致很难让非核心线程发挥作用, 且线程数设置的没必要过多,

本文阐述一种基于业务QPS的设置线程数和队列长度的实践思路. 

线程池理解?

线程池相关的参数, 具体来说包含: 核心线程数、最大线程数、队列类型、队列大小。

要想配的好, 先了解下线程池的作用原理, 以及这些参数对线程池的影响.

任务被创建好后提交到线程池中, 可能会先后经过四个处理步骤: 核心线程 -> 队列缓存-> 非核心线程-> 拒绝策略, 不同步骤中的调度策略也不相同.

  1. 核心线程: 首先判断下核心线程是否已经完成初始化, 若均已完成初始化, 且有余力, 存在空闲线程实例,  那该任务就交给核心线程执行. 核心线程会在线程池创建时进行初始化, 常驻在线程池中, 不会被销毁掉. 其最大并发量由
  2. 队列缓存: 若核心线程已占满, 那就判断是否可先缓存到队列中, 若队列已满存不进去, 进入下一流程
    1. 队列常用两种类型: 阻塞队列与同步队列. 阻塞队列可设置容量, 可缓存一定数量的任务,与正常队列相比, 阻塞队列在空时会阻塞取任务的线程. 同步队列是一种只有一个元素的即存即取队列, 常应用于即时传递场景, 相当于无容量阻塞队列.
  3. 非核心线程: 当队列满了存不进去了, 线程池开始加人手帮忙了, 准确来说是加些临时工, 创建些非核心线程, 这些线程会优先处理源源不断的新进来的任务, 分担核心线程的压力, 没有新任务就从队列去取, 不过采取的是带有超时时间的poll方式, 一段时间拿不到处理任务后, 这些处于空闲状态的非核心线程会被回收, 以免占据系统资源,  临时工数量由最大线程数来决定. 
  4. 最后一步是拒绝策略, 要么抛异常, 要么丢弃掉. 

整个线程池的处理流程可类比餐馆: 有固定的正式员工, 通常数量会比较少, 因为常驻员工要交五险一金、要发工资, 成本较高, 临时工通常是天结, 干完就走, 但也不是无限招, 那数量怎么确定呢?另外客人来了可能会排队, 但也不能无限排, 实在处理不过来就忍痛拒绝客人用餐, 避免餐馆过载,影响正常客人的用餐.  

基于QPS的设置思路?

线程数的确定与餐馆招多少员工、正式占比多少、预留多少临时工思路是一样的,  看总客人数和单个服务员一天所能服务的人数, 单人服务数由单个客人的用餐时长决定, 时长越长, 要求的员工数越多才能支持足够的订单量. 但客人的时长波动, 若按平均时长决定的员工数比较小, 但能够满足日常的客人用餐需求了; 最大时长决定的也是最大员工数, 该数量肯定会富裕, 不过可以应对节假日这种高峰期场景了. 所以根据avg确定核心线程数, 根据tp999或max决定最大线程数.

另外是队列长度, 就是容纳等待任务的数量, 对于流量稳定的服务来说, 其等候区可以设置小些, 为了提升用户体验, 不要让客人等, 多召些临时工就行, 来一个就赶紧招待了, 不让客人等太久, 若临时工招满了也招待不过来, 那就拒绝吧, 免得浪费客人时间, 因为流量稳定, 意味着当前客人到来的速率是稳定大于餐馆的最大处理能力, 若设置等待区, 等待区一直爆满, 队列积压, 导致每个任务都会等一段时间才能被处理, 拉高整体耗时, 此时应该做的是扩容而非等待, 这是同步队列的应用场景,.

另外一种阻塞队列, 适用于高低峰错位的流量不均的情况, 高峰时请求来了, 先在队列中等下, 等待线程依次处理, 高峰处理不过来, 但低峰就会慢慢消化掉, 就是耗时会长点, 若队列满了, 赶紧加临时线程, 避免请求处理失败了. 队列多长合适呢? 建议是核心线程数的3倍, 一个经验值. 过大就导致占据更多资源且整体耗时上涨, 需要及时加人手处理. 

总结?
  • 线程数
    • 与总QPS与单个请求的耗时相关, 总QPS越多、耗时越长要求的线程数越多, 但qps和耗时都是波动的, 所以存在最大值与最小值的要求, 公式= 总qps/(1000/耗时), 耗时单位ms
      • 最大线程数的最小值(核心线程数) = min(avg(qps) / {1000 / avg(耗时)}, processorNum*2}
      • 最大线程数的最大值(总线程数) = min{max(qps) / {1000 / max(耗时)}, processorNum*4}
    • 这种方式也把机器核数的限制考虑进来, 在机器核数与公式线程数之间取最小即可.
  • 队列: 
    • 对稳定流量, 选同步队列或将核心线程数设置大一些.
    • 对高低峰不均流量, 选阻塞队列, 队列长度设置线程数的3~5倍是合适的, 看机器内存大小, 但不要使用无界队列(队列长度默认为整数最大值), 机器会疯.

更多有趣有料技术实践好文请关注,  @ 猫叔的技术日记

感谢你的时间阅读本文, 希望给你带来收获!
线程池中线程数量与队列大小参数的如何设置实践-基于QPS的计算公式icon-default.png?t=N7T8https://mp.weixin.qq.com/s/mlPxfFV2GjzS6e1qU7N5tA

Java线程池实现原理及其在美团业务中的实践 - 美团技术团队本文开篇简述线程池概念和用途,接着结合线程池的源码,帮助读者领略线程池的设计思路,最后回归实践,通过案例讲述使用线程池遇到的问题,并给出了一种动态化线程池解决方案。icon-default.png?t=N7T8https://tech.meituan.com/2020/04/02/java-pooling-pratice-in-meituan.html 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

rabbitmq基础-java-5、Topic交换机

1、简介 Topic类型的Exchange与Direct相比,都是可以根据RoutingKey把消息路由到不同的队列。 只不过Topic类型Exchange可以让队列在绑定BindingKey 的时候使用通配符! BindingKey 一般都是有一个或多个单词组成,多个单词之间以.分割&#x…

使用Python的pygame库实现迷宫游戏

使用Python的pygame库实现迷宫游戏 关于Python中pygame游戏模块的安装使用可见 https://blog.csdn.net/cnds123/article/details/119514520 先给出效果图: 这个游戏能自动生成迷宫布局。 在这个游戏中,玩家将使用键盘箭头键来移动,并且目标…

深入了解达梦数据库的增删查改操作:从入门到精通

目录 前言: 一.达梦数据库的增删改查 1.创建数据库 2.插入数据 3.查看数据 4.删除数据 5.数据 前言: 在当今数字化的时代,数据库已经成为企业和组织的核心资产,是实现高效数据处理、存储和管理的重要工具。达梦数据库&…

测试用例评审流程

1:评审的过程 A:开始前做好如下准备 1、确定需要评审的原因 2、确定进行评审的时机 3、确定参与评审人员 4、明确评审的内容 5、确定评审结束标准 6、提前至少一天将需要评审的内容以邮件的形式发送给评审会议相关人员。并注明详审时间、地点及偿参与人员等。 7、 在邮件中提醒…

科创板交易规则科普

一、交易时间: 交易日的上午9:30-11:30,下午13:00-15:00,其中9:15-9:25是开盘价公布以及竞价的时间,15:05-15:30是盘后固定价格交易时间。 二、买卖原则: 科创板实行T1交易,按照市场实时价格…

Linux运维实战:CentOS7.6操作系统(Shell脚本基础)

文章目录 第19章 Shell脚本基础19.1 Shell基本语法19.1.1 什么是Shell19.1.2 编程语言分类1.低级语言2.高级语言19.1.3 什么是Shell脚本19.2 Shell变量及运用19.2.1 Shell变量1.变量的设置规则如下2.按照变量的作用可以分成以下4类3.按照变量的作用域可以把变量分成两类:…

音乐证书通过率发布,市场对持有者需求旺盛

音乐证书的考试难度备受关注,通过率终于揭晓。据官方公布的数据,该证书的通过率相对较低,需要考生在音乐技能和表现方面有出色的表现。然而,持有音乐证书的人才在市场上需求旺盛,各种音乐机构和企业对其表现出强烈兴趣…

SpringBoot整合ElasticSearch实现分页查询

本文使用SpringBoot整合ElasticSearch实现分页查询 文章目录 环境准备分页查询方式一方式二 本文小结 环境准备 还是继续使用spring-boot-starter-data-elasticsearch来实现分页查询操作 <!-- spring-boot-starter-data-elasticsearch--> <dependency><groupId&…

基于SpringBoot + vue 的旅游景区网站系统设计与实现

目录 一、需求分析 二、技术分析 三、功能分析 四、数据设计 五、界面展示 六、资源获取 一、需求分析 旅游推荐网站是指提供旅游相关信息、服务和建议的在线平台。这些网站旨在帮助用户规划和安排旅行&#xff0c;提供目的地信息、酒店预订、机票预订、租车服务、旅行建…

antv/g6绘制数据流向图

antv/g6绘制数据流向图 前言接口模拟数据htmlts页面效果 前言 在业务开发中需要绘制数据流向图&#xff0c;由于echarts关系图的限制以及需求的特殊要求&#xff0c;转而使用antv/g6实现&#xff0c;本文以代码的方式实现数据流向需求以及节点分组,版本"antv/g6": “…

从零学习开发一个RISC-V操作系统(四)丨RISC-V汇编语言编程

本篇文章的内容 一、RISC-V汇编语言简介1.1 RISC-V 汇编语言的基本格式1.2 RISC-V 汇编指令操作对象1.3 RISC-V 汇编指令编码格式1.4 RISC-V 汇编指令分类 二、RISC-V汇编语言详解2.1 add 加法指令2.2 sub 减法指令 本系列是博主参考B站课程学习开发一个RISC-V的操作系统的学习…

linux条件判断练习

1.实现自动生成相应的压缩包 1.写一个脚本&#xff0c;完成如下功能 传递一个参数给脚本&#xff0c;此参数为gzip、bzip2或者xz三者之一&#xff1b; (1) 如果参数1的值为gzip&#xff0c;则使用tar和gzip归档压缩/etc目录至/backups目录中&#xff0c;并命名为/backups/etc-…

PPP协议原理介绍+报文分析+配置指导-RFC1661

个人认为&#xff0c;理解报文就理解了协议。通过报文中的字段可以理解协议在交互过程中相关传递的信息&#xff0c;更加便于理解协议。 因此本文将在PPP协议报文的基础上进行介绍。 关于PPP协议基本原理&#xff0c;可参考RFC1661-The Point-to-Point Protocol (PPP)。 关于P…

【JavaEE】文件操作 —— IO

文件操作 —— IO 1. 文件的属性 文件内容文件大小文件路径文件名称 2. 文件的管理 采用树形结构进行管理。 3. 文件路径 分为两种&#xff1a;相对、绝对路径。 相对路径&#xff1a;相对于当前位置的路径&#xff0c;以“./xxx.xxx”为标志绝对路径&#xff1a;以从盘符…

手动导入jar包到Maven的解决方案(简单有效!)

想要导入一个jar包到项目中&#xff0c;这个jar包在Maven中没有可以尝试以下方式。 第一步 先找到你maven的本地仓库&#xff0c;我的仓库就在这里&#xff0c;你可以根据你安装的maven找到你的目录 第二步 根据坐标创建文件夹。 这个依赖modbus4j.jar&#xff0c;Maven远…

PyQt ------ QTextEditor

PyQt ------ QTextEditor 引言正文示例1------进阶示例 引言 这里给大家介绍一下 PyQt6 中的 QTextEditor 组件用法。 正文 QTextEditor 可以进行多行字符串输出的组件。 想要获取 QTextEditor 组件中当前存放的字符串&#xff0c;需要使用&#xff1a; QTextEditor.toPla…

《GreenPlum系列》GreenPlum初级教程-GreenPlum详细入门教程

文章目录 GreenPlum详细入门教程第一章 GreenPlum介绍1.MPP架构介绍2.GreenPlum介绍3.GreenPlum数据库架构4.GreenPlum数据库优缺点 第二章 GreenPlum单节点安装1.Docker创建centos容器1.1 拉取centos7镜像1.2 创建容器1.3 进入容器1.4 容器和服务器免密操作1.4.1 生成密钥1.4.…

idea创建公用依赖包项目

创建parent项目 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/…

服务器管理平台(6)- Utils

Utils 本篇为服务器管理平台的结篇&#xff0c;讲述一些必要的Util&#xff0c;如钉钉告警、安全加密、远程登录等功能的实现 1、钉钉告警 1.1、SQL配置告警规则 逻辑磁盘容量已使用比例超过90% 超过30天未登录 字段名称字段类型解释Idint自增IDTablestring监测表名Metri…

matlab appdesigner系列-常用18-表格

表格&#xff0c;常用来导入外部表格数据 示例&#xff1a; 导入外界excel数据&#xff1a;data.xlsx 姓名年龄城市王一18长沙王二21上海王三56武汉王四47北京王五88成都王六23长春 操作步骤如下&#xff1a; 1&#xff09;将表格拖拽到画布上 2&#xff09;对app1右键进行…