并发测试队列堆积和请求丢失往往相伴而生,当系统处理速度跟不上并发量时,未处理的请求开始在队列中积压,一旦队列溢出或超时机制触发,就会出现请求丢失。
排查思路从现象到根源进行分层排查。
第一步:确定丢失发生在哪一层。是客户端请求未发出去(网络/线程池满),还是服务端前置队列满丢弃,还是消息中间件(如Kafka、RabbitMQ)丢失,还是处理完成后响应丢失。
第二步:监控队列堆积标准。查看服务端请求队列、线程池队列、消息中间件的消费延迟或未确定消息数,判断哪个步骤成为短板。
第三步:分析资源短板。CPU、内存、IO、网络带宽、文件描述符等,应用线程池配置是不是合理(线程最大线程、队列容量、拒绝方法)。
第四步:检查上下游超时和重试方法。客户端超时时间过短导致提前断开,服务端仍在处理,响应丢弃;或者重试风暴加剧堆积。检查连接超时、读超时设置。
第五步:业务思路和锁竞争。检查是不是存在慢SQL、长事务、锁等待导致线程阻塞,造成队列堆积,进而触发拒绝方法丢弃请求。
第六步:消息中间件排查。如果是消息队列,检查分区数、消费者组内消费者数量、消费能力,确定是不是因为消息重平衡导致短暂丢失;检查自动提交还是手动提交位移,防止重复消费或丢失消息。
第七步:日志和链路追踪。增大请求级别日志,配合trace id,确认请求在哪个节点消失不见,比对客户端发出、服务端接收、服务端返回的日志。
第八步:复现测试和配置调优。适当扩大队列容量、调整线程池参数、关闭非必要日志、优化SQL、增加实例等。