首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >mysql--连接器阻塞了不再存在的连接。猫冻

mysql--连接器阻塞了不再存在的连接。猫冻
EN

Stack Overflow用户
提问于 2013-03-12 12:49:12
回答 2查看 1.8K关注 0票数 2

我们在Tomcat中使用JDBCRealm和mysql进行表单身份验证。这几乎总是工作得很好。

当我们停止/重新启动mysql数据库(在测试中)时,我们注意到Tomcat线程中的一个将无休止地等待一些与身份验证相关的数据,而不是失败(例如,IOException或超时或其他什么)。这会导致所有其他HTTP线程在需要共享同步方法时也会阻塞。结果是,越来越多的HTTP线程被创建,所有阻塞,直到达到最大值。

冻结的线程永远不会醒来或超时,即使我使用netstat来确认它所阻塞的连接是否有效地消失了。

双方之间都有防火墙,尽管我不认为这与这里的问题有任何关系。这些连接是“正常”建立和拆除的。

快速解决方案当然是用数据库停止/启动tomcat,但似乎奇怪的是,调用不会简单地失败。另外,我担心在类似的情况下,这种情况也会发生在生产中。

除了重新启动tomcat或手动关闭阻塞线程之外,还有什么可以做的吗?

提前谢谢你的想法。

设置:

  • tomcat6
  • 用于表单认证的JDBCRealm
  • mysql 5.5数据库
  • mysql-connector-java-5.1.7-bin.jar

Server.xml的相关部分:

代码语言:javascript
运行
复制
  <Realm className="org.apache.catalina.realm.LockOutRealm" lockOutTime="300">
       <Realm className="org.apache.catalina.realm.JDBCRealm"
            connectionName="xxx"
            connectionPassword="xxx"
            connectionURL="jdbc:mysql://xxx:6446/xxx?autoReconnect=true"
            digest="xxx"
            driverName="com.mysql.jdbc.Driver"
            roleNameCol="xxx"
            userCredCol="xxx"
            userNameCol="xxx"
            userRoleTable="xxx"
            userTable="xxx"
            maxActive="30"
            maxIdle="30"
            maxWait="10000"
            factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory"/>
  </Realm>

阻塞线程的示例(在输入“同步”方法时阻塞):

代码语言:javascript
运行
复制
Name: http-8080-60
State: BLOCKED on org.apache.catalina.realm.JDBCRealm@edeb18b owned by: http-8080-61
Total blocked: 27  Total waited: 63

Stack trace: 
 org.apache.catalina.realm.JDBCRealm.authenticate(JDBCRealm.java:353)
org.apache.catalina.realm.CombinedRealm.authenticate(CombinedRealm.java:178)
org.apache.catalina.realm.LockOutRealm.authenticate(LockOutRealm.java:196)
org.apache.catalina.authenticator.FormAuthenticator.authenticate(FormAuthenticator.java:260)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:454)
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
org.apache.catalina.authenticator.SingleSignOn.invoke(SingleSignOn.java:394)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
java.lang.Thread.run(Unknown Source)

导致所有其他线程中的块的单个线程(注意,"available()“调用正在等待/阻塞一个不再存在的连接):

代码语言:javascript
运行
复制
Name: http-8080-61
State: RUNNABLE
Total blocked: 132  Total waited: 1,198

Stack trace: 
 java.net.PlainSocketImpl.socketAvailable(Native Method)
java.net.PlainSocketImpl.available(Unknown Source)
   - locked java.net.SocksSocketImpl@c679aa4
java.net.SocketInputStream.available(Unknown Source)
com.mysql.jdbc.util.ReadAheadInputStream.available(ReadAheadInputStream.java:231)
com.mysql.jdbc.MysqlIO.clearInputStream(MysqlIO.java:941)
com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1887)
com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2101)
com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2548)
   - locked java.lang.Object@65d98b58
com.mysql.jdbc.ConnectionImpl.commit(ConnectionImpl.java:1560)
   - locked java.lang.Object@65d98b58
org.apache.catalina.realm.JDBCRealm.getPassword(JDBCRealm.java:583)
   - locked org.apache.catalina.realm.JDBCRealm@edeb18b
org.apache.catalina.realm.JDBCRealm.authenticate(JDBCRealm.java:414)
   - locked org.apache.catalina.realm.JDBCRealm@edeb18b
org.apache.catalina.realm.JDBCRealm.authenticate(JDBCRealm.java:361)
   - locked org.apache.catalina.realm.JDBCRealm@edeb18b
org.apache.catalina.realm.CombinedRealm.authenticate(CombinedRealm.java:178)
org.apache.catalina.realm.LockOutRealm.authenticate(LockOutRealm.java:196)
org.apache.catalina.authenticator.FormAuthenticator.authenticate(FormAuthenticator.java:260)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:454)
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
org.apache.catalina.authenticator.SingleSignOn.invoke(SingleSignOn.java:394)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
java.lang.Thread.run(Unknown Source)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-03-12 13:13:04

尝试在使用socketTimeout的JDBC连接上设置读取超时。

代码语言:javascript
运行
复制
jdbc:mysql://xxx:6446/xxx?autoReconnect=true&connectTimeout=60000&socketTimeout=60000
票数 1
EN

Stack Overflow用户

发布于 2013-03-12 13:25:57

您是否只在四度使用数据库?您应该更好地使用与DataSourceRealmLockOutRealm相结合的数据源。也许最后这一项与JDBCRealm没有很好地集成。

下面是一个JDBCRealm javadoc摘要:

For a Realm implementation that supports connection pooling and doesn't require synchronisation of authenticate(), getPassword(), roles() and getPrincipal() or the ugly connection logic use the DataSourceRealm.

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15361675

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档