问题描述
我们有几个 .NET Core 3.0 Web 应用程序(英国南部),它们连接到在 Amazon Windows Server 2016 数据中心(EC2 实例)上运行的 MS sql 2016 数据库。我们通过安装在 sql Server 上的 Azure 中继/混合连接进行连接。
它已经运行了一年多没有错误,但最近我们开始收到以下错误,大约每 30 个连接中就有一个:
处理请求时发生未处理的异常。 Win32Exception: 现有连接被远程主机强行关闭。 未知位置
sqlException: 已成功与服务器建立连接,但是 然后在登录前握手期间发生错误。 (提供者:TCP 提供者, 错误:0 - 远程主机强行关闭了现有连接。)
如果你再试一次,它通常会奏效。
在阅读了大量关于此的帖子后,我使用 EnableRetryOnFailure() 到数据库连接为代码/弹性添加了瞬态错误处理。
我还尝试将 Trusted_Connection=False 添加到连接字符串中。
此后,您可以看到连接重试多次,直到成功,有时需要 20 秒或更长时间。尽管如此,可能有 100 个连接最终失败并出现相同的错误。
我们还查看了 TLS_DHE 错误 https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/apps-forcibly-closed-tls-connection-errors,但服务器上根本没有安装 TLS_DHE 密码。
Windows 服务器上的事件日志或发生错误时的数据库日志中没有任何内容。
基础架构的最新变化:Panda 防病毒软件,将 Web 应用移至不同的 Azure 区域。
我几天来一直在阅读有关此的帖子,大部分内容非常陈旧且略有不同。我正在寻找任何想法来尝试查明错误。谢谢。
编辑:我在 Microsoft/ServiceBus/Client 中发现了一些事件日志
HybridConnectionManager 跟踪:Microsoft.Azure.Relay.RelayException:无法从传输连接读取数据:远程主机强行关闭了现有连接。 ---> System.Net.WebSockets.WebSocketException: 发生内部 WebSocket 错误。有关更多详细信息,请参阅innerException(如果存在)。 ---> System.IO.IOException: 无法从传输连接读取数据:远程主机强行关闭了现有连接。 ---> System.Net.sockets.socketException: 一个现有的连接被远程主机强行关闭 在 System.Net.sockets.socket.EndReceive(IAsyncResult asyncResult) 在 System.Net.sockets.NetworkStream.EndRead(IAsyncResult asyncResult) --- 内部异常堆栈跟踪结束---
解决方法
嗯,这花了三个月的时间来解决,涉及到我们的网络支持团队、AWS 支持和 Azure 支持。
我已经回来编辑这个答案三遍了。解决方案在另一台服务器上返回,因此我们尝试了在一台服务器上有效的修复程序,但没有奏效!
在 Azure Relay/Hyrbid 连接中,在有问题的连接下,我们看到有两个侦听器,而应该只有一个。您安装和连接的每个混合连接管理器都显示为侦听器。
那么第二个听众在哪里?无处。它似乎是来自先前删除的连接的挂起孤立链接。
删除幻听监听器的唯一方法是
- 在数据库服务器上卸载 HCM
- 从所有使用它的 azure 应用程序中删除连接
- 在 azure 中完全删除混合连接
- 重新在 azure 中重新创建连接
- 重新连接应用
- 在数据库服务器上重新安装 HCM
- 将 HCM 连接到新的混合连接
此后,我们在 Azure 连接下展示了一个侦听器,一切立即生效。
当您有两个侦听器时,数据会在它们之间进行负载平衡,因此在我的情况下,有一半时间数据被路由到不存在的侦听器并失败。这就是为什么没有日志出现在数据库服务器上 - 它根本没有到达那里!