一、线程池问题
线程池不仅仅是配置参数的问题,更多在于平衡性能和机器的使用情况下的综合平衡。
二、关注要点
2.1 接口调用量
2.2 单个线程执行时间
考虑接口调用量同时要兼考虑单个线程执行时间,防止多个线程执行下,任务调度/其他多线程触发导致线程
2.3 CPU余量
要同时考虑cpu和内存余量
在cpu占用不多情况下,我们是在优化程序。
在cpu打满了,再创建线程是给OOM创造条件。
2.4 线程的独占和共享问题
独占好处:业务不影响。
共享好处:线程公用,防止太多的独占线程 导致程序崩溃。
三、相关策略
3.1一般情况采用拒绝策略
采用拒绝策略,防止cpu堆积太多对象。
拒绝了之后怎么解决呢?
能快速失败的就丢弃就好了,(直接失败)
如果不能丢弃的,那么就需要记录日志,类似mysql的redo日志,实现数据/接口的回放。实现最终一致性。
回放逻辑在BurpSuite中有重放攻击,我们在处理的时候也需要关注幂等处理
具体策略
AbortPolicy 默认策略(中止策略)新任务提交时直接抛出未检查的异常RejectedExecutionException,该异常可由调用者捕获。
DiscardPolicy 丢尾
丢弃策略,丢弃队列尾部的任务请求,即丢弃最新进来的任务请求。
DiscardOldestPolicy 丢头
丢弃策略,丢弃队列头部的任务请求,即丢弃最老进来的任务请求
3.2 抛回策略
这是一种不好的机制,让调用者自己处理,一般来说调用者是主线程,如果为了减少自己的压力,把问题抛回给了主线程(提出问题的人);那主线程如果崩溃了,这个事情也是有问题的。
CallerRunsPolicy
为调节机制,既不抛弃任务也不抛出异常,而是将某些任务回退到调用者。不会在线程池的线程中执行新的任务,而是在调用exector的线程中运行新的任务。
四、线程池参数是否合理
4.1 判定标准
通过cpu和内存占用来比对
cpu和内存的余量很大,说明就不合理
如何计算?
单个线程占用判断
单线程内存(mb)* 线程数(num)= 总占用内存
虚拟线程解决上下文切换的问题,线程号切换。
refer
参考刘老师的架构理解