【问题标题】:SYN receives RST,ACK very frequentlySYN 接收 RST,ACK 非常频繁
【发布时间】:2012-03-24 05:18:09
【问题描述】:

您好 Socket 编程专家,

我正在 Linux 上为在 Windows 上运行的 SQL Server 2005/2008 编写代理服务器。 代理是使用 bsd 套接字和 C 编码的,它可以很好地解决下面描述的问题。

当我使用数据库客户端(用 JAVA 编写,在 Linux 机器上运行)直接向数据库服务器发起查询(并发 100 或更多)时,没有遇到连接重置。但是通过我的代理,我遇到了许多连接重置。

深入挖掘后,我了解到从“数据库客户端”到“代理”的连接总是成功的 但是当“代理”尝试连接到数据库服务器时,连接失败,因为 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 客户端(直接到服务器)在任何时候都可以正常工作。

【问题讨论】:

  • 我假设当您谈论“在 Windows 上运行的 SQL 数据库”时,您正在谈论 SQL Server。如有必要,请更改标签,但请注意:缺少重要信息。
  • 感谢 JayC,我认为这与手头的问题无关。编辑它。

标签: sql-server linux sockets proxy network-programming


【解决方案1】:

SQL Server 需要worker threads 才能接受传入连接。如果您的服务器缺少工作人员(可以通过sys.dm_os_tasks 中的大量条目在PENDING 状态下轻松诊断),那么尝试打开新连接将失败。我怀疑发生的事情很可能是您向服务器推送了它可以处理的更多工作负载。您需要优化工作负载或获得更强大的服务器。

像 Java 客户端这样的客户端有效地利用了connection pooling,即使在高负载下也不需要打开新连接,因此您不会看到这个问题,而是只会看到请求完成的延迟。

【讨论】:

  • 嗨 Remus,感谢您的回复。我没有在 JAVA 客户端中启用连接池。即使启用它,使用池时连接也不会关闭,并且由于我使用的是同一个客户端,因此也不会通过代理看到问题。在打开新连接时会看到问题。查看sys.dm_os_tasks,发现在400并发时,有68个连接处于PENDING状态。
  • 他们在PENDING 状态停留了多长时间?使用sys.dm_os_waiting_tasks.wait_duration。这与您使用 Java 客户端时相比如何?
  • 它们会在很短的时间内保持待定状态。当我再次检查时,它们消失了。即使我将 JAVA 客户端直接(指向服务器)指向服务器端,一些连接也会在服务器端处于 PENDING 状态很短的时间。我认为这可能不会捕获重置的连接,因为它是由 TCP 层本身处理的,而应用程序没有意识到它们的存在。我不知道 sys.dm_os_waiting_tasks 是否向操作系统查询此类信息。使用wireshark,我可以清楚地看到从代理服务器返回的RST、ACK SYN。
【解决方案2】:

监听套接字保持已建立连接的队列和建立过程中的连接(例如 SYN 已收到,SYNACK 已回复,但尚未收到来自客户端的 ACK)。如果已建立的队列溢出,IP 堆栈反应在 OS 上会有所不同。最传统的方法是忽略新的 SYN,等待用户态的 accept() 并释放队列中的一个槽。随着 90 年代中期的 SYN 泛洪攻击,发明了一种名为“SYN cookie”的新方法,它完全不需要建立队列,代价是需要支持特殊的 TCP 选项。 OTOH 我听说 Windows 堆栈改变了它们的行为——在某些情况下,对队列溢出的反应是 RST 响应。在早期的堆栈(例如 Win95)中,这是主要响应,客户端相应地更改为忽略对 SYN 的 RST 响应:( 这就是为什么我猜测某些代理主机功能会触发 Windows 堆栈中的 RST。

另一个猜测是数据库服务器在某些情况下(例如检测到过载峰值)完全关闭了侦听套接字,这仅在代理中出现。

【讨论】:

  • 您好 Netch,感谢您的回复,您的意思是我必须让我的代理忽略这种特殊情况并在实际失败之前重试连接一段时间.....在您的最后一句话中,您说“仅与代理一起出现”。数据库服务器可以知道它正在与代理或实际客户端通信吗??
【解决方案3】:

当SYN收到RST响应时,应该不是SQL-SERVER的问题。

因为应用程序只有在 tcp 握手完成后才能accept 套接字。

Proxy 和 SQL-Server 机器之间是否有任何设备?

尝试确保 RST 响应来自 sql-server 机器。

我认为你的连接数远非 SYN-FLOOD。

【讨论】:

  • 您好,llj098,这是一个好点。将验证 RST 是否仅出现在代理 m/c 和服务器 m/c 之间。当问题再次出现时,也可以通过从代理 m/c 运行 JAVA 客户端来检查这一点。会更新你。
猜你喜欢
  • 1970-01-01
  • 2020-04-24
  • 2016-02-17
  • 2016-04-11
  • 1970-01-01
  • 2015-07-04
  • 1970-01-01
  • 2020-03-19
  • 1970-01-01
相关资源
最近更新 更多