ActiveMQ:No operations allowed after statement closed问题及解决办法

 
ActiveMQ版本:5.5.1

现象:

系统现象:部分消息发送失败,失败频率不正常。
日志信息:activemq.log 中一直有这样的错误日志:

JDBC Failure: No operations allowed after statement closed.

com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after statement closed.

at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)

…………

at org.apache.activemq.transport.InactivityMonitor.onCommand(InactivityMonitor.java:227)

at org.apache.activemq.transport.TransportSupport.doConsume(TransportSupport.java:83)

at org.apache.activemq.transport.tcp.TcpTransport.doRun(TcpTransport.java:220)

at org.apache.activemq.transport.tcp.TcpTransport.run(TcpTransport.java:202)

at java.lang.Thread.run(Thread.java:662)

Close failed: Already closed.

看上去又是 mq broker 失去了数据库连接,但代码仍尝试在此连接上执行操作,所以 jdbc 直接抛异常。

原因:

ActiveMQ 持久化方案我们选的是 MySQL 。
如果 mq 与 db 之间的数据库连接,因为数小时的不活动(inactivity),那么 MySQL 就会根据自身的 wait_timeout 参数设置主动断开连接。这一点在之前的“ActiveMQ:Communications link failure问题以及解决办法”文章中讲过。
只不过,遇到此问题时,
mq client 端报告“com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure”错误,
而 mq server 端则报告“ com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after statement closed. ”错误。
即原因是,mq broker service 试图在已关闭的数据库连接上继续执行操作
缺陷单 AMQ-2534 甚至报告“

Broker gets stuck with an error about using a closed JDBC statement

”,我们很难说此时 mq broker service 会不会真的“卡住”。
 
解决办法:

跟“ActiveMQ:Communications link failure问题以及解决办法”文章讲的一样,
最简单办法,还是根据业务特点,调整 ActiveMQ 所使用的 MySQL 的全局变量 wait_timeout 值,
尽量减少数据库连接因为 inactivity 而被关闭的几率 。
 
或者在 mq client 里主动捕获 com.mysql.jdbc.exceptions.jdbc4.CommunicationsException 异常,手动重新连接即可:
  1. } catch (SQLException sqlEx) {
  2. String sqlState = sqlEx.getSQLState();
  3. // 08S01就是这个异常的sql状态。单独处理手动重新连接即可。
  4. if ("08S01".equals(sqlState) || "40001".equals(sqlState))
 

为什么 Connector/J 不自动重连而非要抛出异常:

下面的文字翻译自 MySQL 5.5 Connect/J 疑难问题文档
23.3.15.13: 为什么遇到 communication failure 之后, Connector/J 不能自己重新连上数据库,然后重新提交事务呢,而是非要抛出一个异常,即使我用了 autoReconnect 连接字符串属性?
答:有几个原因。
第一个,保证事务完整性。MySQL 的帮助文档上曾说过:“there is no safe method of reconnecting to the MySQL server without risking some corruption of the connection state or database state information”。
可以看一下这个案例:
01.conn.createStatement().execute(
"UPDATE checking_account SET balance = balance - 1000.00 WHERE customer='Smith'");
02.conn.createStatement().execute(
"UPDATE savings_account SET balance = balance + 1000.00 WHERE customer='Smith'");
03.conn.commit();
考虑一下这个场景:执行完01后,数据库连接断了。
如果没有异常抛出的话,应用程序永远不知道这个问题,仍继续执行。
但是第一个事务并没有提交,所以它回滚了。
如果没抛异常,数据库连接自动重连,于是第二个事务被提交了。
从而破坏了事务完整性(transactional integrity)。
 
记住,此时 auto-commit 于事无补。当 Connector/J 遇到 communication problem ,你不知道服务器端是否处理了这个事务,有几种可能:
  • 服务器端没有接到这个事务,因此什么也没发生;
  • 服务器端接到了且执行了,但客户端没有收到 Response 。
 
第二个原因是,事务里上下文相关数据有可能非常脆弱,如:
  • 临时表;
  • 用户自定义变量;
  • 服务器端预处理语句(Server-side prepared statements);
如果数据库连接断开了,很可能这些数据也消失了;如果此时不抛出异常而是自动重连,你的应用程序很可能跑飞了。
 
总结:
1)silently reconnecting”可能非常不安全,将衍生出很多不可控问题。所以最佳策略是,通知应用程序到底发生了什么,然后由应用开发者决定如何处理
2)mq的生产者频繁报“com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure”和mq server自己频繁报“com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after statement closed. ”,都是因为 mysql 的 wait_timeout 导致数据库连接因为不活动而被主动关闭。
 
本文引自:http://www.cnblogs.com/zhengyun_ustc/archive/2012/11/10/activemq_inactivity.html

MQ异常断开的更多相关文章

  1. SSH乱码和Xshell异常断开解决方法

    一.SSH Secure Shell Client中文乱码的解决方法 这是SSH Secure Shell Client多年未解决的短板,要求客户端和服务器端都要‘UTF-8’编码,我终于知道Wind ...

  2. socket选项自带的TCP异常断开检测

    TCP异常断开是指在突然断电,直接拔网线等等情况下,如果通信双方没有进行数据发送通信等处理的时候,无法获知连接已经断开的情况. 在通常的情况下,为了使得socket通信不受操作系统的限制,需要自己在应 ...

  3. 在c#中利用keep-alive处理socket网络异常断开的方法

    本文摘自 http://www.z6688.com/info/57987-1.htm 最近我负责一个IM项目的开发,服务端和客户端采用TCP协议连接.服务端采用C#开发,客户端采用Delphi开发.在 ...

  4. TCP连接异常断开检测(转)

    TCP是一种面向连接的协议,连接的建立和断开需要通过收发相应的分节来实现.某些时候,由于网络的故障或是一方主机的突然崩溃而另一方无法检测到,以致始终保持着不存在的连接.下面介绍一种方法来检测这种异常断 ...

  5. (转)TCP连接异常断开检测

    TCP是一种面向连接的协议,连接的建立和断开需要通过收发相应的分节来实现.某些时候,由于网络的故障或是一方主机的突然崩溃而另一方无法检测到,以致始终保持着不存在的连接.下面介绍一种方法来检测这种异常断 ...

  6. freeradius防止用户异常断开无法重新链接上

    freeradius防止用户异常断开无法重新链接上 http://www.cnblogs.com/klobohyz/archive/2012/02/08/2342532.html 编辑default文 ...

  7. python 服务端判断客户端异常断开

    在进行 python 套接字编程时,服务端程序要判断客户端是否异常断开[由于断电或者其他突发情况导致链接中断],可以通过以下几种方式判断: 1.如果通信协议中,设有心跳包,则可记录上次收到时间,将服务 ...

  8. 针对TCP连接异常断开的分析

    我们知道,一个基于TCP/IP的客户端-服务器的程序中,正常情况下,我会是启动服务器使其在一个端口上监听请求,等待客户端的连接:通过TCP的三次握手,客户端能够通过socket建立一个到服务器的连接: ...

  9. PHP - 用户异常断开连接,脚本强制继续执行,异常退出回调

    试想如下情况.如果你的用户正在执行一个需要非常长的执行时间的操作.他点了执行了之后,浏览器就开始蛋疼地转.如果执行5分钟,你猜他会干啥,显然会觉得什么狗屎垃圾站,这么久都不响应,然后就给关了.当然这个 ...

  10. linux 服务器与客户端异常断开连接问题

    服务器与客户端连接,客户端异常断掉之后服务器端口仍然被占用, 到最后是不是服务器端达到最大连接数就没法连接了?领导让我测试这种情况,我用自己的电脑当TCP Client,虚拟机当服务器,连接之后能正常 ...

随机推荐

  1. robots.txt详解[通俗易懂]

    大家好,又见面了,我是你们的朋友全栈君. 怎样查看robots文件? 浏览器输入 主域名/robots.txt robots.txt的作用 robots.txt 文件规定了搜索引擎抓取工具可以访问网站 ...

  2. 利用Canal投递MySQL Binlog到Kafka

    https://www.aboutyun.com/thread-27654-1-1.html https://www.cnblogs.com/bigdatalearnshare/p/13832709. ...

  3. 基础篇之Markdown基础语法

    标题 1. # + 空格 + 标题名字 → 一级标题 2. ## + 空格 + 标题名字 → 二级标题 3. ### + 空格 + 标题名字 → 三级标题 ...... 6.###### + 空格 + ...

  4. jquery语言中获取input标签后如何给input标签添加disabled的属性

    jquery语言中获取input标签后如何给input标签添加disabled的属性 1.使用JQuery函数prop():$("input").prop("disabl ...

  5. C#实现Bitmap旋转

    原文链接 Rotate180FlipNone 指定不进行翻转的 180 度旋转.Rotate180FlipX 指定后接水平翻转的 180 度旋转.Rotate180FlipXY 指定后接水平翻转和垂直 ...

  6. 1.JavaScript的实现与由来

    1.一个JavaScript由不同的部分组成 核心(ECMAScript)以下简称ES 文档对象模型(DOM) 浏览器对象模型(BOM) ES就是JavaScript的语法层面 而DOM则是浏览器解释 ...

  7. linux下使用bt-rm 限速删除文件

    下载限速删除工具: 链接:https://pan.baidu.com/s/1xXu4Hzr99wLlipqxVkXkBg 密码:upbe nohup ./bt-rm -l 10 ${文件地址} &am ...

  8. Docker基本命令之 容器管理

    容器管理 查看正在运行的容器: docker ps 查看完整信息:docker ps --no-trunc 查看在运行或停止运行的容器:docker ps -a 查看容器系统资源的使用情况:docke ...

  9. MySQL 面试题总结

    MySQL的面试知识点总结 Q1:MySQL 的逻辑架构了解吗? 第一层是服务器层,主要提供连接处理.授权认证.安全等功能. 第二层实现了 MySQL 核心服务功能,包括查询解析.分析.优化.缓存以及 ...

  10. JS Math与一些原始类型

    镇楼图 Pixiv:DSマイル 一.值属性.函数 globalThis JS有全局对象,但是在不同环境中全局对象均不同.在Web环境中,window.self.frames取得全局对象,在Web Wo ...