首页 > 数据库 >高并发下 MySQL Statement Cancellation Timer 的线程数暴涨

高并发下 MySQL Statement Cancellation Timer 的线程数暴涨

时间:2024-01-06 11:32:51浏览次数:48  
标签:image factory Timer 线程 Statement mysql com png

微信公众号:运维开发故事

作者:老郑

问题描述

线上业务高峰期 CPU 飙升,抓取 thread dump 发现 MySQL Statement Cancellation Timer 的线程数比较多,接收到线上预警,分析一下原因。

业务高峰:

高并发下 MySQL Statement Cancellation Timer 的线程数暴涨_MySQL


下面是一些可能相关的信息( mysql 驱动,db 连接池,orm 框架)

依赖信息:

  1. mysql-jdbc 8.0.24
  2. druid 1.2.8
  3. mybatis 3.4.6

环境配置信息

  1. druid 配置,全部都是默认值
  2. mybatis 配置:
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
    SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
    factory.setVfs(SpringBootVFS.class);
    factory.setDataSource(dataSource);
    //todo 省略其他配置
    Configuration c = new Configuration();
    c.setLogImpl(StdOutImpl.class);
    c.setDefaultStatementTimeout(25000);
    factory.setConfiguration(c);

    return factory.getObject();
}

发生过程分析

  1. 找到该线程的创建的地方 NativeSession

高并发下 MySQL Statement Cancellation Timer 的线程数暴涨_MySQL_02

  1. 引用关系如下

高并发下 MySQL Statement Cancellation Timer 的线程数暴涨_mysql_03

image.png

  1. 什么时候启动 enableQueryTimeouts = true

高并发下 MySQL Statement Cancellation Timer 的线程数暴涨_mysql_04

image.png

  1. 默认值是 true

高并发下 MySQL Statement Cancellation Timer 的线程数暴涨_mysql_05

image.png

  1. startQueryTime 的调用方 StatementImpl 的 executeQuery

高并发下 MySQL Statement Cancellation Timer 的线程数暴涨_mysql_06

image.png

  1. 可以发现 timeOutInMillis 不为 0 的情况下,并且 enableQueryTimeouts = true 就会创建 CanalQueryTask 然后如果超时就会自动调度

方法调用如下:com.mysql.cj.CancelQueryTaskImpl#run

高并发下 MySQL Statement Cancellation Timer 的线程数暴涨_MySQL_07

处理方案

  1. 项目使用的是使用 alibaba druid

高并发下 MySQL Statement Cancellation Timer 的线程数暴涨_mysql_08


参考:https://github.com/alibaba/druid/wiki/DruidDataSource%E9%85%8D%E7%BD%AE%E5%B1%9E%E6%80%A7%E5%88%97%E8%A1%A8

调用的是 setQueryTimeOut 方法,然后传给 timeOutInMills

高并发下 MySQL Statement Cancellation Timer 的线程数暴涨_MySQL_09


如果需要取消 CancelQueryTask 需要将 validationQueryTimeout 设置为 0

  1. 并且去掉 mybatis defalutStatemnetTimeOut 参数

高并发下 MySQL Statement Cancellation Timer 的线程数暴涨_java_10

image.png

  1. 如果这些都去掉可以通过 mysql  服务端 collection timeout 配置处理
  • mysql 服务器会有一个参数 wait_timeout:mysql server 关闭连接之前,允许连接闲置多少秒。默认是 28800,单位秒,即 8 个小时。
# 分别查看全局、会话变量值
show global VARIABLES like '%timeout%';
show  VARIABLES like '%timeout%';

高并发下 MySQL Statement Cancellation Timer 的线程数暴涨_mysql_11

image.png

  • druid 可以通过 testOnBorrow 和 testOnReturn、testWhileIdle分别在链接获取,链接归还的时候判断是否有效。

高并发下 MySQL Statement Cancellation Timer 的线程数暴涨_java_12

image.png


复现和修复

测试代码

  • PushCallbackService.java
  • CallbackLog.java
  • DBTimerController.java
  • MccClient.java

修复效果

现象 MySQL Statement Cancellation Timer的线程不再产生

高并发下 MySQL Statement Cancellation Timer 的线程数暴涨_MySQL_13

thread dump 分析工具地址:https://fastthread.io/

参考资料


最后,求关注。如果你还想看更多优质原创文章,欢迎关注我们的公众号「运维开发故事」。

标签:image,factory,Timer,线程,Statement,mysql,com,png
From: https://blog.51cto.com/u_12970189/9126215

相关文章

  • JVM2(线程)
    (1)线程这里所说的线程指程序执行过程中的一个线程实体。JVM允许一个应用并发执行多个线程。HotspotJVM中的Java线程与原生操作系统线程有直接的映射关系。当线程本地存储、缓冲区分配、同步对象、栈、程序计数器等准备好以后,就会创建一个操作系统原生线程。Java线程结束,原......
  • 多线程(互斥锁,条件变量,虚假唤醒)知识点总结
    互斥锁mutexC++11一共提出四种互斥锁std::mutex:独占的互斥锁,不能递归使用std::timed_mutex:带超时的独占互斥锁,不能递归使用std::recursive_mutex:递归互斥锁,不带超时功能std::recursive_timed_mutex:带超时的递归互斥锁1.mutexmutex有三个成员函数:voidlock();booltry_loc......
  • 【Redis技术专区】「原理分析」深入探索和分析Redis6.0为何需要启用多线程
    背景介绍在Redis6.0版本中,引入了多线程技术,这是为了进一步提高Redis的性能和并发处理能力。通过启用多线程,Redis能够同时处理多个客户端请求,有效地利用多核处理器资源,提高系统的吞吐量和响应速度。开启多线程可以在处理阻塞操作时提供更好的性能,例如慢查询、持久化操作等。此外,多......
  • 【设计模式】单例模式——利用ThreadLocal或CAS实现单线程内部的单例模式
    很多时候我们并不需要一个类创建的对象是全局唯一的,只需要保证在单个线程内是唯一的、线程安全的就可以。为了实现单线程内部的单例,我们可以用ThreadLocal或CAS实现。利用ThreadLocal实现先看代码:publicclassThreadLocalSingleton{privatestaticfinalThreadLocal<Thread......
  • swoole运行Master 进程、Reactor 线程、Worker 进程、Task 进程、Manager 进程的区别
    Master进程、Reactor线程、Worker进程、Task进程、Manager进程的区别与联系Master进程Master进程是一个多线程进程Reactor线程Reactor线程是在Master进程中创建的线程负责维护客户端TCP连接、处理网络IO、处理协议、收发数据不执行任何PHP代码将TCP客户......
  • 用Spring Boot 3.2虚拟线程搭建静态文件服务器有多快?
    SpringBoot3.2于2023年11月大张旗鼓地发布,标志着Java开发领域的一个关键时刻。这一突破性的版本引入了一系列革命性的功能,包括:虚拟线程:利用ProjectLoom的虚拟线程释放可扩展性,从而减少资源消耗并增强并发性。NativeImage支持:通过NativeImage编译制作速度极快的应......
  • 聊一聊 C# 的线程本地存储TLS到底是什么
    聊一聊C#的线程本地存储TLS到底是什么 一:背景1.讲故事有朋友在后台留言让我说一下C#的 ThreadStatic 线程本地存储是怎么玩的?这么说吧,C#的ThreadStatic是假的,因为C#完全是由CLR(C++)承载的,言外之意C#的线程本地存储,用的就是用C++运行时提供的 __declspec(thread) 或 ......
  • 记一次协程|线程|进程学习记录
    本章仅以获取图片来测试一下Py的同步、异步、协程、多进程、多线程的速度。凑个热闹即可,具体需要以实际情况为主。图片数量:257张执行操作:1、读取文件2、发起请求3、下载图片所需库:pipinstallhttpxpipinstallaiomultiprocesspipinstallaiofilespipinstallrequests同步def......
  • 深入分析 Java、Kotlin、Go 的线程和协程
    文章目录前言协程是什么协程的好处进程进程是什么进程组成进程特征线程线程是什么线程组成任务调度进程与线程的区别线程的实现模型一对一模型多对一模型多对多模型线程的“并发”协程协程的目的协程的特点协程的原理Java、Kotlin、Go的线程与协程Kotlin的协程使用「线程」的代......
  • QProgressDialog用法及结合QThread用法,四种线程使用
    1QProgressDialog概述QProgressDialog类提供耗时操作的进度条。进度对话框用于向用户指示操作将花费多长时间,并演示应用程序没有冻结。此外,QPorgressDialog还可以给用户一个中止操作的机会。进度对话框的一个常见问题是很难知道何时使用它们;操作在不同的硬件上花费不同的时间......