- 工作线程数是否设置越大越好
服务器cpu核数有限,能够同时并发的线程数有限
线程切换有开销,如果线程切换过于频繁,反而会使性能下降
- 单核cpu,设置多线程,提高并发性能
多线程编码可以让代码更清晰,例如IO线程收发包,worker线程进行任务处理,timeout线程进行超时检测,通常来说,worker线程一般不会占用cpu进行计算,因此增加worker线程数可以提高并发能力
- 互联网常见线程服务模型
- io线程和worker线程通过任务队列解耦
- 纯异步
worker线程模型,内部是同步阻塞执行任务的。
纯异步模型,没有阻塞,只需要设置很少的线程就可以做到很高吞吐量,
缺点是:
如果利用单线程模式,难以利用多cpu多核的优势
更习惯于写同步代码,callback的方式对代码的可读性有冲击,要求很高
框架更复杂,需要server端收发组件、server端队列、client收发组件、client队列。。。
- 工作线程的工作模式
1)从工作队列中拿出任务,进行一些本地初始化计算,例如http协议分析,参数解析,参数校验等
2)访问cache数据
3)拿到cache里面的数据后,再进行一些和业务相关的本地计算
4)通过rpc调用下游service再拿一些数据,或者让下游service处理一些相关的任务
5)rpc调用结束后,在进行一下本地计算
6)访问db进行一些数据操作
7)操作完数据库之后进行一些收尾工作,收尾工作也是本地计算
分析:
1)3)5)7)线程进行本地业务逻辑计算,需要占用cpu,而2)4)6)步骤中,访问cache、rpc、db出于一个等待结果的状态,不需要占用cpu,进一步分解,"等待结果"状态分为三部分:
请求在网络上传递到下游的cache、rpc、db
下游的cache、rpc、db进行任务处理
cache、rpc、db将报文在网络上传回工作线程
- 量化分析并合理设置工作线程数
通过分析可知,worker线程在执行的过程中,有一部分计算需要占用cpu,另一部分等待时间不需要占用cpu, 通过量化分析,例如打印日志进行统计,可以统计出这两部分的时间的比例。
结论:
N核服务器,通过执行业务的单线程分析出本地计算时间为X,等待时间为Y,则工作线程数为
N*(X+Y)/X,能让cpu利用率最大
- 经验:
cpu密集型业务:加解密,压缩解压缩、搜索排序等业务,本地计算时间比较多
非cpu密集型业务:访问cache、rpc、db等
一般非cpu密集型业务瓶颈都在后端数据库访问和rpc调用,增加工作线程数可以提升吞吐量。