一次问题排查思路,
涉及问题点:
mq:为消费端,默认数据已经消费到
线程池:多线程处理数据
数据库连接池:连接数据库做增删改查等操作
排除分布式问题,幂等问题,已处理。
测试配置:
线程池配置:
核心线程池数量:4
最大线程池数量:4
队列:1
等待时间5s
数据库连接池配置:
数据库连接池:2
最大连接数:2
最大等待时间:2s
压测数据量:10个
问题复现:在数据处理的时候睡两秒,此时四个线程争抢两个数据库连接池资源,每个操作超过两秒,抢到资源的两个工单执行完毕后,后面等待的必然会数据库连接超时,出现 time out
问题二复现:
数据丢失问题:
1.数据丢失有两种情况:
a) 数据库操作超时导致的数据回滚丢失
b) 线程池队列和处理线程满了导致新的数据过来直接抛异常:它会抛出RejectedExecutionException异常,并且直接丢弃数据。(目前队列足够长)
c) 线程超时,导致线程在完成后提交的时候报错(扩展情况,)
以上问题总结:
1.由于需要快速的并行,所以使用异步,线程池配置如果太小,根据线程池的拒绝策略会丢失大量数据,所以线程池队列必须配置需要根据要求设置足够大,按照实际业务处理数据时间和数据量来定(暂不考虑机器配置问题)
2.根据线程池的大小,计算数据库连接池,由于数据库连接池主要耗时间在于增删改,启动了事务,(以十条为例)计算出一个线程处理十条数据总时间,计算出对应数据库连接池(数据量连接池理论上越小越好,线程太多会增加cpu处理切换线程开销,导致系统层面速度降低),所以需要通过测试找到一个平衡值,首先要确保数据丢失最低,单位时间内数据处理完,其次又确保系统的资源开销处于最低,还要考虑线程之间的数据库连接池资源争抢导致线程数量释放太慢的问题,轻则资源占用高,cpu使用率飙升,重则系统崩溃,oom(这一点应该就是核心线程数为什么不会设置太多的原因)。