我是一名开发人员,设计一款网络服务时,遇到了好与坏的情况,而这款服务将受到 iPhone 客户端的严重打击。去年,这款 iPhone 应用的下载量超过 1000 万次,现在,我要让用户在线上相互交流。
我想调整将托管我的基于 TCP 的网络服务的服务器的 TCP 实现。发送的每个请求大小将“很小”(例如 < 256 字节)。好的,你猜对了,这是一个游戏服务器(令人震惊!)。
仅供参考,对于此特定服务,我对 UDP(或 ENet 和 RakNet 中所示的 UDP 上的可靠层)不感兴趣,因为游戏与 Quake 不同;所有数据包都必须可靠接收,而这正是 TCP 的设计目的。因此,iPhone 客户端和服务之间的连接将“长期存在”(尽可能长——隧道和电梯见鬼去吧!)。
仅供参考,我在运行 Linux 2.6.18-164.9.1.el5 的服务器上以 100Mbps 上行链路运行该服务。
我的目标是同时:
- 保持尽可能低的延迟;
- 尽量减少每个连接客户端使用的内存量。
有一个大的需要调整的 TCP 相关旋钮数量!经过一些基本研究,似乎大多数人建议保留原样。但是,有许多设置似乎就像它们应该针对特定情况进行调整一样。我知道这有点模糊,这就是我寻求帮助的原因。
在尽可能减少内存的同时,需要考虑调整不稳定网络上的小请求/响应,例如:
- TCP/IP 实现可用的内存
- 设置“nodelay”选项(禁用 Nagle 算法,因为这是一个半实时游戏服务器)
- 拥塞控制算法
- 等等(还有什么?)
考虑 TCP拥塞控制算法:
- reno:几乎所有其他操作系统都使用的传统 TCP
- 立方:CUBIC-TCP
- bic:BIC-TCP
- htcp: 汉密尔顿TCP
- 拉斯维加斯:TCP Vegas
- westwood:针对有损网络进行了优化
我的服务器默认比克其“目标是设计一种协议,可以在高速长距离网络上将其性能扩展到每秒几十千兆位,同时保持强大的公平性、稳定性和 TCP 友好性。”
仅从简短的描述来看,韦斯特伍德听起来更恰当,因为它“旨在更好地处理大带宽延迟产品路径(大管道),由于传输或其他错误而导致的潜在数据包丢失(泄漏管道),以及动态负载(动态管道)”。
我是不是陷入太深了,还是这只是正常现象?
你们通常针对哪些方面来调整 TCP/IP?如何调整?有哪些经验法则需要了解?
针对我的这个特殊情况,您有什么忠告吗?
多谢!
答案1
因此,正如您所发现的,TCP 拥塞控制是一个非常复杂的领域。
对于这种特殊情况,由于请求较小,您将需要尽可能保持连接打开,因为每个请求的一个连接将需要五个数据包,而如果您保持连接,则可以将平均值降至略多于两个数据包。
NODELAY 对于游戏服务器来说是正确的选择;您希望立即传送 256 个字节,而这不是整个段,因此除非您使用 NODELAY,否则 Nagle 将会暂停。
如果您的服务器有大量内存,那么内存选项就不是什么大问题,新内核已经为它们做好了准备。
至于拥塞控制算法,您发现了 Westwood。另一个选项是 CUBIC。您可以只使用其中一种,也可以做一些研究并对其进行基准测试。这可能需要相当多的工作,但对于 10M 客户端来说,这是值得的。因此,我会考虑使用 Mac 或三台 Mac 上的流量生成器(因为它们具有与手机相同的 TCP 实现)、充当路由器的 Linux 机器(稍后会详细介绍)和您的一台服务器来运行模拟,看看效果如何。
现在,中间的 Linux 机器应该运行ns-3因此,您可以模拟比以太网交换机更复杂的路径。然后,您可以在 TCP 连接的发送端捕获一些数据包跟踪,并使用跟踪或者 wireshark 的 tcptrace 图形模式。tcptrace 文档是分析 TCP 拥塞行为的良好入门指南。