无标题文档
来源:无标题文档
口播文案
天天用线程池,面试官问线程数咋设?你慌不慌?
咱做开发的,天天跟线程池打交道:处理订单用它,同步数据也用它!可一到面试,面试官问 “不同任务线程数咋设”,你是不是只能说 “大概设 20 个?” 别慌!今天咱不光讲原理,还带 3 个真实工作场景,把 CPU 密集、IO 密集的线程数设置讲透,听完你立马能对标自己的项目!
先从最常见的CPU 密集型场景说起 —— 比如 “订单金额汇总”!之前公司做月度对账,要把 10 万条订单数据拉出来,算每个用户的总消费额:先过滤无效订单,再按用户 ID 分组,最后累加金额。你猜这任务里 CPU 和 IO 占比多少?整个过程几乎不用查数据库、不用读文件,全是内存里的计算操作,单个任务耗时 150 毫秒,其中 145 毫秒 CPU 都在算,IO 操作就 5 毫秒(顶多读个配置文件),典型的 “CPU 干到冒烟,IO 闲得打盹”!
这种情况线程数咋设?就按 “CPU 核心数” 来!当时服务器是 16 核的,我把线程数设成 16,跑下来 10 万条数据只用了 2 分钟;后来有人想 “多设线程会不会更快”,改成 32 个,结果反而用了 3 分半 —— 为啥?因为线程多了,CPU 得不停切换任务,光切换就浪费了不少时间!所以记住:CPU 密集任务,线程数≈CPU 核心数,像大数据排序、加密解密这些场景,都这么设!
再重点说最容易懵的 IO 密集型场景,给你举两个真实例子,你肯定碰到过!
第一个场景:调用第三方支付接口!比如用户下单后,要调用微信支付的接口生成支付链接。这个过程中,咱的服务干了啥?就传个订单号、金额过去,然后等着微信服务器返回链接 —— 这等待的时间就是 “IO 等待”!我之前测过,单个调用耗时 800 毫秒,其中 780 毫秒都在等微信接口响应,CPU 真正处理参数、解析返回值的时间才 20 毫秒,IO 等待占比高达 97.5%!
这种场景线程数可不能少!当时服务器是 8 核的,按公式算:8÷(1-0.975)=320 个线程。我设了 300 个线程(留 20 个给其他服务),原本每秒只能处理 10 个调用,改完后每秒能处理 300 个,完全能扛住高峰期的下单量!要是还按 8 个线程设,每秒顶多处理 10 个,用户得一直转圈等支付链接,早投诉了!
第二个 IO 密集场景:批量上传 Excel 数据!之前做员工信息导入,用户传一个 5 万行的 Excel,服务要先读 Excel 文件(IO),再查数据库判断员工是否已存在(IO),最后插入新员工(IO)。整个任务耗时 1200 毫秒,其中读文件 300 毫秒、查数据库 600 毫秒、写数据库 250 毫秒,CPU 处理数据格式的时间才 50 毫秒,IO 等待占比快 96%!
当时我用 8 核服务器,按公式算 8÷(1-0.96)=200 个线程,设完后 5 万行数据 10 分钟就导完了。之前有人按 “经验” 设 20 个线程,导了 1 个小时还没结束,用户直接把 Excel 扔群里说 “系统卡死了”—— 这就是没搞懂 IO 密集任务的坑!
最后说混合密集型场景—— 比如 “商品详情页渲染”!这个接口要干三件事:查数据库拿商品基础信息(IO)、调用库存服务查库存(IO)、把商品信息和库存数据组装成详情页格式(CPU)。你看,又有 IO 操作,又有 CPU 操作,要是放一个线程池里,查数据库等 300 毫秒时,CPU 就空着;组装数据时,IO 又闲着,多浪费!
我当时拆成了两个线程池:IO 密集池和 CPU 密集池。IO 池处理查数据库、调库存接口,按 8 核服务器算,设了 160 个线程;CPU 池处理数据组装,设了 8 个线程。改完后,接口响应时间从 500 毫秒降到 200 毫秒,高峰期也没卡过 —— 这就是拆分的魔力!
现在你再看:CPU 密集找 “计算类场景”,线程数跟核心数走;IO 密集找 “等接口、等数据库的场景”,按公式算;混合场景就拆分!下次面试官问,你就把 “订单汇总、支付接口、Excel 导入” 这三个场景一说,再算遍公式,他指定觉得你不是 “纸上谈兵”,是真在项目里用过!赶紧收藏,下次调线程池直接对标,稳了!