Hi Socket Programming专家,
我正在Linux上为在Windows上运行的SQL Server 2005/2008编写代理服务器。 代理使用bsd套接字和C语言进行编码,它可以正常工作,并解决下面描述的问题。
当我使用数据库客户端(用JAVA编写,并在Linux机器上运行)直接向数据库服务器发出查询(并发度为100或更高)时,没有遇到连接重置。但通过我的代理我遇到了很多连接重置。
深入挖掘我开始知道从'DB客户端'到'代理'的连接总是成功的 但是当'Proxy'尝试连接到DB服务器时,连接失败,因为SYN数据包获得了RST,ACK。
那是为了给出一些背景知识。问题是 : 为什么有时SYN收到RST,ACK?
DB client(linux) to Server(windows) ----> Works fine
DB client(linux) to Proxy(Linux) to Server(windows) -----> problematic
我知道这可能发生在“拒绝连接”的情况下,但这肯定不是那个。 SYN泛滥可能是另一种情况,但这并不能解释直接向服务器发送时的良好行为。
我怀疑可能需要一些套接字选项设置,客户端在连接之前执行,而我的代理没有。请详细说明一下。任何帮助(链接或指针)都非常感谢。
其他信息:
写了一个执行并发连接的C客户端,它以并发作为参数。以下是我的观察: - >在5000并发及以上,一些连接失败'拒绝连接'。 - > 2000年以下,它运作良好。
但即使在100或更高的并发度下也会观察到实际问题。 注意:问题是时间相关的,有时它永远不会发生,有时它非常频繁,DB客户端(直接服务器)始终可以正常工作。
答案 0 :(得分:1)
SQL Server需要worker threads来接受传入连接。如果您的服务器缺乏工作(可以通过PENDING
状态sys.dm_os_tasks
中的大量条目轻松诊断),则尝试打开新连接将失败。所以我怀疑它发生的可能性是你正在向服务器推送它可以处理的更多工作量。您需要优化工作负载或获得更强大的服务器。
像Java客户端这样的客户端有效地使用connection pooling,即使在高负载下,也不需要打开新连接,因此您没有看到此问题,而是只看到请求完成的延迟。
答案 1 :(得分:0)
侦听套接字在建立过程中保持已建立连接和连接的队列(例如,SYN got,SYNACK已回复,但尚未从客户端回复)。如果已建立的队列溢出,则IP堆栈响应因操作系统而异。最传统的方法是忽略新的SYN,等待userland accept()并释放队列中的一个槽。随着90年代中期的SYN泛洪攻击,新方法被发明命名为“SYN cookies”,完全降低了对建立队列的需求,需要支持特殊的TCP选项。 OTOH我听说Windows堆栈改变了它们的行为 - 在某些情况下,对队列溢出的反应是RST响应。在早期的堆栈(例如Win95)中,这是主响应,客户端相应地更改为忽略RST对SYN的响应:( 这就是为什么我猜一些代理主机功能会触发Windows堆栈中的RST。
另一个猜测是,DB服务器在某些情况下(例如检测到的过载峰值)完全关闭侦听套接字,这种情况只出现在代理服务器上。
答案 2 :(得分:0)
当SYN收到RST响应时,它不应该是SQL-SERVER的问题。
因为只有在tcp握手完成后,应用程序才能accept
套接字。
Proxy和SQL-Server机器之间是否有任何设备?
尝试确保RST响应来自sql-server machine。
我认为你的连接数远远不是SYN-FLOOD。