IOCP 和 EPOLL 服务器的 TCPKeepAlive 与 KeepAliveTimeout | eSeGeCe 博客

IOCP 和 EPOLL 服务器的 TCPKeepAlive 与 KeepAliveTimeout

· 组件
sgcWebSockets IOCP 和 EPOLL 服务器的 TCPKeepAlive 与 KeepAliveTimeout

sgcWebSockets 中的 IOCP(Windows)和 EPOLL(Linux)服务器引擎使用一小组线程池处理数千个连接,而不是为每个连接分配一个线程,这正是它们成为高并发负载服务器首选方案的原因。然而直到现在,它们都没有办法察觉一个悄悄消失、没有道别的对端。两个新选项,TCPKeepAliveKeepAliveTimeout,填补了这一空白。

静默对端永远不会产生事件

IOCP 和 EPOLL 都是事件驱动的:引擎会一直休眠,直到操作系统通知它某个套接字有数据、已关闭或发生了错误。这种机制运行良好,直到某个对端在没有发送干净的 FIN 或 RST 的情况下消失,例如客户端崩溃、NAT 或防火墙丢弃了空闲映射,或者路由悄然发生了变化。该套接字将不会再收到任何事件,因此连接会在服务器上无限期地保持 ESTABLISHED 状态。

传统的每连接一线程 IOHandler 不存在这个问题,因为每个连接都会以带超时的方式阻塞在读取操作上,因此一旦下一次读取超时,静默连接就会被发现并释放。IOCP 和 EPOLL 此前并没有等效的机制,而这正是这两个新选项所补充的内容。

TCPKeepAlive:让操作系统来监视

启用 TCPKeepAlive 后,一旦连接空闲达到 Time 秒,操作系统就会自行开始探测该连接,此后每隔 Interval 秒重复一次探测,直到对端响应或连接被断开。该选项默认关闭;下面的数值与启用后的默认值一致。

Server.IOHandlerOptions.IOHandlerType := iohEPOLL;
Server.IOHandlerOptions.EPOLL.TCPKeepAlive.Enabled  := True;
Server.IOHandlerOptions.EPOLL.TCPKeepAlive.Time     := 60;  // seconds idle before probing
Server.IOHandlerOptions.EPOLL.TCPKeepAlive.Interval := 10;  // seconds between probes

在 Windows 服务器上,相同的三个属性位于 IOHandlerOptions.IOCP.TCPKeepAlive 下。

KeepAliveTimeout:应用层空闲超时

KeepAliveTimeout 采用了一种不同的、更直接的方式:只要连接空闲时间超过设定的秒数,它就会将其关闭,而不管操作系统的 keepalive 探测结果如何。这与每连接一线程 IOHandler 释放静默连接的方式最为接近,它默认是禁用的(值为 0),并且只影响真正处于空闲状态的连接,正在读取的请求或正在写入的响应都不会被它中断。

Server.IOHandlerOptions.EPOLL.KeepAliveTimeout := 120; // seconds

// Windows
Server.IOHandlerOptions.IOCP.KeepAliveTimeout := 120;

请将其设置为明显高于你预期最慢的请求或响应耗时,例如典型的 HTTP 或 WebSocket 服务器可以设为 120 秒,这样真正失效的连接能被迅速清理,同时不会误伤只是响应较慢的连接。

检测断线的第三种方式

sgcWebSockets 此前已经提供了两种察觉对端离线的方式:在 TsgcWebSocketClient 上启用 CleanDisconnect,让行为规范的客户端在离开前通知服务器;或者在服务器端运行 heartbeat,按固定间隔对每个客户端发送 ping。这两种方式都依赖于配合,前者依赖客户端的配合,后者依赖你自己实现的 ping/pong 往返。TCPKeepAliveKeepAliveTimeout 是第一个完全不需要这些配合的方案:服务器完全依靠自身就能检测到失效的连接。

可用性

这两个选项现已在适用于 Delphi 和 C++ Builder 7 到 13 的 sgcWebSockets 中提供,位于 IOHandlerOptions.EPOLLIOHandlerOptions.IOCP 下,与现有的 EPOLLThreadsIOCPThreadsWorkOpThreads 设置并列。它们默认关闭,因此除非你主动开启,否则现有服务器不会有任何变化。

下载试用版,并在 sgcWebSockets 产品页面阅读完整的 IOCP 和 EPOLL 参考文档。

有疑问或反馈?联系我们,回复你的将是编写这些代码的人。