当前位置: 首页 > 科技观察

MQ-消息堆积-一条SQL阻塞整个服务线程案例分析

时间:2023-03-11 22:17:55 科技观察

业务背景业务中的应用在消费MQ时,一些机器消息堆积。随着时间的推移,积累的机器数量会越来越多。消息的累积总量正在增加。现象描述系统监控CPU、Load、内存、网络、磁盘监控指标正常;JVM内存和GC都正常。MQ监控图1消费者状态分析过程中MQ消息堆积最常见的情况是应用端处理MQ消息慢,触发了MQ的流控机制(当MQ统计显示应用消费慢时,会逐渐减少到应用端,最坏的情况下MQ单条消息不会发送到应用端消费)。下一个念头在哪里放慢?在业务监控完整的情况下,通过分析业务监控指标,可以大致定位异常点,明确运行程序在忙什么,分析线程堆栈信息。堆栈信息图2堆栈信息上图中TID=562的线程正在读取返回的Oracle信息。经过观察,TID=562的线程一直处于上图中的状态。由于上图的stack信息不完整,所以用jstack抓取后分析一个关键信息:lockedoracle.jdbc.driver.T4CConnection@31c02e79T4CConnection分析[oracle.jdbc.driver.T4CConnection@31c02e79]是与Oracle交互的数据库对于connection对象,需要分析connection对象对应的socket信息,connection对象正在执行的SQL,connection对象关联的statements对象信息这方面的分析:Socket和Socket的交互Oracle服务器:图5连接数据的TCP连接信息//通过tcpdump分析与Oracle服务器交互的报文,发现连接上没有报文交互tcpdump-ianytcpandport45556-A-nnQ:向OracleDBA确认Socket在服务器端执行的是什么SQL?答:我没有找到任何关于SocketSQL的资料。通过分析oracle.jdbc.driver.T4CConnection类代码和[oracle.jdbc.driver.T4CConnection@31c02e79]属性信息,找到了正在执行的SQL和连接关联的语句。资料:SQL:图6SQLstatements:图7SQL参数值至此,我们分析了造成线程阻塞的SQL细节。解决方法是过滤掉参数为null的情况,不再向Oracle发送这样的SQL语句;同时将这种异常情况记录在日志中,更详细地分析数据为null的场景。通过线程执行耗时监控增强应用程序可观察性○在业务逻辑开始前添加过滤器○当请求到达过滤器时,将当前线程和当前时间记录在一个Map中○请求结束时返回过滤器删除当前线程从Map中○启动一个单独的定时任务遍历Map,当发现Map中某个线程执行时间超过阈值时,打印出线程栈○当开发者收到异常告警堆栈,手动干预系统恢复和快速问题定位。

猜你喜欢