上下文:云

我们有一个基于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)

堆栈跟踪示例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)

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

  • 一些要点
  • 我们从来没有见过这个问题
    运行该应用程序数年的我们自己的环境(即自己的数据中心)
  • 这使我得出结论:“Amazon网络环境正在发生一些有趣的事情”。我可能是错的/缺少某些东西/等。
  • 此问题仅在我们的应用程序中发生。我们还有其他的Java和php应用程序,这些应用程序都没有这个问题。另一个Java应用程序使用不同的jdbc驱动程序(jtds,afaik)
  • 似乎不是简单的连接超时

  • 问题

    -有没有人见过这个?
    -如果这是EC2的“已知问题”,我们是否可以配置解决问题的方法(即确保所有内容都在其自己的子网或虚拟私有(private)云(vpc)上?
    -任何jdbc驱动程序设置都可以克服此问题?

    ** 更新 **
    我扩大了对这个问题的悬赏。

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

    在非云环境中,两台服务器之间存在“零跳”。

    我们的托管管理员说,我们无法控制EC2实例的子网。这让我想知道虚拟私有(private)云是否会有所帮助。

    提前致谢

    将要

    最佳答案

    在使用usind 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/)

    关于sql-server - SQL Server JDBC连接重置错误: Only on Amazon EC2,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6231778/

    10-10 13:51
    查看更多