Sql Server JDBC连接重置错误:仅在Amazon EC2上

use*_*465 12 sql-server jboss jdbc amazon-ec2 java-ee

背景:云

我们有一个基于Java的Web应用程序,我们通常在自己的服务器上托管.最近,我们使用Amazon Web Services(AWS EC2)云来托管实例.

这种"云设置"与我们典型的"现场"设置相匹配:应用服务器的一台服务器,数据库服务器的另一台服务器.(多个应用服务器指向同一个数据库服务器)

问题 在这个云设置中,我们在数据库和jdbc驱动程序之间接收间歇性的"通过对等错误重置连接",其中(看似)随机间隔和代码库中的随机点,数据库连接失败.

以下是日志的一些错误摘录

堆栈跟踪示例1:

at com.participate.pe.genericdisplay.client.taglib.GenDisplayViewTag.doStartTag(GenDisplayViewTag.java:77)
    ... 75 more
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: The connection is closed.
    at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:170)
    at com.microsoft.sqlserver.jdbc.SQLServerConnection.checkClosed(SQLServerConnection.java:304)
    at com.microsoft.sqlserver.jdbc.SQLServerConnection.getMetaData(SQLServerConnection.java:1734)
    at org.jboss.resource.adapter.jdbc.WrappedConnection.getMetaData(WrappedConnection.java:354)
Run Code Online (Sandbox Code Playgroud)

堆栈跟踪示例2

    at java.lang.Thread.run(Thread.java:619)
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Connection reset
    at com.microsoft.sqlserver.jdbc.SQLServerConnection.terminate(SQLServerConnection.java:1368)
    at com.microsoft.sqlserver.jdbc.SQLServerConnection.terminate(SQLServerConnection.java:1355)
    at com.microsoft.sqlserver.jdbc.TDSChannel.read(IOBuffer.java:1532)
    at com.microsoft.sqlserver.jdbc.TDSReader.readPacket(IOBuffer.java:3274)
    at com.microsoft.sqlserver.jdbc.TDSCommand.startResponse(IOBuffer.java:4437)
    at com.microsoft.sqlserver.jdbc.TDSCommand.startResponse(IOBuffer.java:4389)
    at com.microsoft.sqlserver.jdbc.SQLServerConnection$1ConnectionCommand.doExecute(SQLServerConnection.java:1457)
    at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:4026)
    at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:1416)
    at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectionCommand(SQLServerConnection.java:1462)
    at com.microsoft.sqlserver.jdbc.SQLServerConnection.setAutoCommit(SQLServerConnection.java:1610)
    at org.jboss.resource.adapter.jdbc.BaseWrapperManagedConnection.checkTransaction(BaseWrapperManagedConnection.java:429)
Run Code Online (Sandbox Code Playgroud)

技术环境

  • Jboss 4.2.2.GA(Jboss-Web 2.0/Tomcat 6)
  • MSSQL 2005 2.0 jdbc驱动程序

有些观点

  • 我们从未在我们自己的环境(即自己的数据中心)中运行应用程序多年来看到这个问题
  • 这让我得出结论"亚马逊网络环境正在发生一些有趣的事情".我可能错了/遗漏了某些东西/等等.
  • 此问题仅发生在我们的应用程序中.我们有其他java和php应用程序没有这个问题.另一个java应用程序使用不同的jdbc驱动程序(jtds,afaik)
  • 它似乎不是一个简单的连接超时

问题

-谁看过这个吗? - 如果这是一个EC2"已知问题",我们可以配置解决问题的方法(即确保一切都在自己的子网或虚拟私有云(vpc)? - 任何jdbc驱动程序设置来解决这个问题?

**更新**我已经延长并增加了对这个问题的赏金.

额外信息:两个虚拟服务器(数据库和应用服务器)位于不同的子网上 - 即两个服务器之间的一跳.

在非云环境中,我们在两台服务器上都有"零跳".

我们的托管管理员表示我们无法控制EC2实例的子网.这让我想知道虚拟私有云是否会有所帮助.

提前致谢

小智 2

请注意,使用 DBCP/连接池功能来缓解该问题 - 启用“testOnBorrow”和其他功能越多,就越可能对系统造成延迟或其他性能变化影响。我不知道 DBCP 是否仍然这样做,但几年前它会生成实际的测试查询来测试连接 - 完整堆栈、数据库响应 - 不仅仅是在网络层。Brian 的上述链接带回了 2000 年代初有关 JDBC 连接管理重试逻辑的可怕回忆。

无论如何,除了收集证据并消除一组特定条件的“看似随机”之外,很难真正找到根本原因:

  • 您可以尝试抛出 Wireshark/PCAP 跟踪,查找其发生时间,并将结果发送给 Amazon 和 Microsoft,看看他们是否可以找到根本原因

  • 您可以使用某些测试工具尝试上述方法来隔离问题(JMeter 测试以提高并发性)、反弹网络连接、观察恢复等

  • 您可以尝试使用 SQL Server 的替代版本来消除已修复的 SQL Server/JDBC 驱动程序错误。

  • 如果在连接字符串中使用 DNS,则可以使用 IP 地址来验证 nslookup 问题

我不是 SQL Server 专家,但另一种研究途径可能是在相关产品领域内 - 例如,看看是否有人遇到过类似的 TFS/Sharepoint 问题(例如http://nickhoggard.wordpress.com/2009/12 /07/further-experiences-with-tfs-2010-beta-2-on-amazon-ec2/ )