文档章节

在Tomcat下无法清除MySQL连接线程导致服务挂掉的解决办法

Mechanic
 Mechanic
发布于 2017/05/05 09:32
字数 335
阅读 2296
收藏 1

在Tomcat下无法清除MySQL连接线程,会导致服务挂掉,这是MySQL的bug,MySQL官方BUG信息:https://bugs.mysql.com/bug.php?id=69526。 可以通过建立监听器销毁线程的方式来解决,代码如下:

/*
 * Copyright 2016-2017 TVI Go Easy.
 * Created on 2017/4/25 11:28
 */
package org.mechanic.fund.listener;

import com.mysql.jdbc.AbandonedConnectionCleanupThread;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Profile;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;

/**
 * 清除数据库链接线程。该现象目前只发现在MySQL驱动上存在
 * MySQL官方BUG信息:https://bugs.mysql.com/bug.php?id=69526
 * 避免Tomcat reload application的是无法清除MySQL连接线程时抛出一下异常:
 * org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
 * SEVERE: The web application [/XXX] appears to have started a thread named
 * [Abandoned connection cleanup thread] but has failed to stop it. This is very
 * likely to create a memory leak.
 *
 * [@author](https://my.oschina.net/arthor) mechanic
 * [@version](https://my.oschina.net/u/931210) 0.0.1
 */
@WebListener
@Profile({"test", "release"})
public class AbandonedConnectionCleanupTheardListener implements ServletContextListener {

    private static Logger logger = LoggerFactory.getLogger(AbandonedConnectionCleanupTheardListener.class);

    [@Override](https://my.oschina.net/u/1162528)
    public void contextInitialized(ServletContextEvent sce) {
        logger.info("AbandonedConnectionCleanupTheardListener is started.");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        Enumeration<Driver> drivers = DriverManager.getDrivers();

        Driver driver = null;

        // 清除驱动
        while (drivers.hasMoreElements()) {
            try {
                driver = drivers.nextElement();
                DriverManager.deregisterDriver(driver);
            } catch (SQLException ex) {
                logger.error("注销数据库连接线程失败。这种情况通常出现在MySQL上。");
            }
        }

        // MySQL driver leaves around a thread. This static method cleans it up.
        try {
            AbandonedConnectionCleanupThread.shutdown();
        } catch (InterruptedException e) {
            logger.error("AbandonedConnectionCleanupThread线程关闭失败。这种情况通常出现在MySQL上。");
        }
    }
}

© 著作权归作者所有

Mechanic
粉丝 1
博文 17
码字总数 8748
作品 0
广州
技术主管
私信 提问
一个DLOG4J博客网站频繁宕机的问题解决

这是一个特例,可能不具备普遍的参考意义。 网站:http://www.dlog.cn 系统:Linux + MySQL + Tomcat + Nginx + (DLOG4J) 现象:频繁宕机,网页无法打开,在服务器上测试 Tomcat 的HTTP端口无...

红薯
2009/10/19
604
3
@温少,Druid 能不能源码中增加注释或提交JavaDoc啊?

@wenshao,你的 Druid 源码中能不能加些注释啊?特别是 DruidDataSource 和 DruidAbstractDataSource,目前没有找到任何一个说明文档能够把 DruidDataSource 中所有的setter方法等说明清楚,...

山哥
2016/08/12
311
1
使用java代码启动Tomcat成功后连接不上数据库

最近做一个监听Tomcat的程序,监听Tomcat服务是否挂掉,如果挂掉,就使用代码重启Tomcat服务,具体的功能是实现了,当检测到Tomcat挂掉后,我是通过Runtime.getRuntime().exec("路径\\start...

千里码
2012/12/26
5.1K
3
运行环境为centos7,tomcat和mysql的优化方式,经验总结

一般在服务的cpu占用很高时, 1.使用ps -mp pid -o THREAD,tid,time命令查看该进程的线程情况,可以列举出占用高的线程,挑选个占用高的线程的tid,eg:挑选TID为14065的线程,查看该线程的堆...

lost的熊猫
2017/07/19
0
0
[玩转MySQL之二]MySQL连接机制浅析及运维

前言 使用MySQL数据库的第一步必然是建立连接登录,然后在上面执行SQL命令。无论是通过mysql的客户端,还是通过C-API,JDBC标准接口连接数据库,这个过程一定少不了。那么就不经有几个疑问?...

沈欧邦
2018/09/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

线程池之ThreadPoolExecutor使用

ThreadPoolExecutor提供了四个构造方法: ThreadPoolExecutor构造方法.png 我们以最后一个构造方法(参数最多的那个),对其参数进行解释: public ThreadPoolExecutor(int corePoolSize, /...

天王盖地虎626
21分钟前
1
0
小程序登陆流程

http://www.bubuko.com/infodetail-2592845.html

为何不可1995
30分钟前
1
0
Consul+Spring boot的服务注册和服务注销

一图胜千言 先看一看要做事情,需要在Consul上面实现注册中心的功能,并以2个Spring boot项目分别作为生产者,消费者。 Consul 假设已经完成文章《Consul的开发者模式之Docker版》中的所有的...

亚林瓜子
36分钟前
4
0
MySQL高可用之基于Galera复制跨地域节点分布的滥用

mysql使用教程 MySQL高可用之基于Galera复制跨地域节点分布的滥用 2018-11-22 02:15 8335 85 让我们再一次讨论MySQL高可用性(HA)和同步复制。 它是地理上分布区域上一些高可用性参考架构解...

rootliu
47分钟前
1
0
js判断pc还是移动端

var pcyidong =/(iPhone|iPad|iPod|iOS|Android)/i.test(navigator.userAgent); 如果pcyidong的值为false则用户的浏览器为pc端 如果pcyidong的值为true则用户浏览器为移动端 if (pcyidong =...

流年那么伤
58分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部