【问题标题】:How to disable Nagle's algorithm in ServiceStack?如何在 ServiceStack 中禁用 Nagle 算法?
【发布时间】:2017-09-14 16:19:02
【问题描述】:

我们使用的是 ServiceStack 3.9.71.0,目前我们在通过 WAN 连接的客户端遇到无法解释的延迟问题。

在 200ms+ 后收到带有非常小的有效负载(

由于地理距离的关系,链路上的往返时间 (RTT) 约为 40 毫秒。这已通过 ping 另一台主机并使用简单的 echo 服务测试 TCP 连接的延迟得到验证。

ping 和 echo 测试均显示符合预期的延迟。从我们的 ServiceStack 主机获得回复的时间比预期的要长。

我们已经验证:

  • WAN 链接仅以 25% 的容量运行(无拥塞)
  • WAN 链路上没有使用 QOS
  • 同一主机快速回复来自本地网络上不同主机的同一请求
  • 延迟不是由我们的代码处理请求引起的

我们现在偶然发现了 Nagle 的算法,它可能意味着 WAN 网络上的小请求会出现延迟 (http://blogs.msdn.com/b/windowsazurestorage/archive/2010/06/25/nagle-s-algorithm-is-not-friendly-towards-small-requests.aspx)。

在 .NET 中,可以通过设置 TcpClient.NoDelay = true (https://msdn.microsoft.com/en-us/en-US/library/system.net.sockets.tcpclient.nodelay(v=vs.110).aspx) 来禁用它。

如何禁用 ServiceStack 的 TCP 处理?

编辑:我不认为这是 HttpWebRequest is slow with chunked data 的副本。提到的问题涵盖了 ServiceStack 不使用的HttpWebRequest。 ServiceStack 使用HttpListener,它也恰好由提到的ServicePointManager 控制/管理。我们将进行测试,看看设置ServicePointManager.UseNagleAlgorithm = false是否可以解决问题。

【问题讨论】:

  • 如果你没有找到任何这样的方法来禁用nagle的算法,我建议下载ServiceStack的开源代码并在所有文件中搜索Socket,为所有创建套接字的函数添加一个选项允许 TCP_NODELAY 选项。将代码添加到源以使用 setsocketopt 函数设置 TCP_NODELAY。 msdn.microsoft.com/en-us/library/windows/desktop/…。在您最好在开源 repo 上提交更改之后。这个特定的例子解释了为什么高级 API 会妨碍低级调优。
  • 嗨维克拉姆,感谢您的建议。 ServiceStack 的 v3 源代码在 Github 上公开托管:github.com/ServiceStack/ServiceStack/tree/v3。我进行了快速搜索,但我认为他们不会直接使用Socket。看起来他们正在使用HttpListener - 知道是否可以为HttpListener 设置 TCP_NODELAY 吗?
  • 嗨 Timo,我目前正在使用 linux,但我确实搜索了 repo,发现需要添加更改的 API 在 /src/ServiceStack.Server/Messaging/Rcon/Client 中。 cs & /src/ServiceStack.Server/Messaging/Rcon/Server.cs 。套接字是在函数 connect(Client.cs) 和 start(Server.cs) 中创建的。祝你好运,如果有时间我会做出改变。
  • Vikram,不用担心这两个文件 - AFAIK 它们是我们在项目中不使用的消息队列实现的一部分,所以如果我是没记错。
  • HttpWebRequest is slow with chunked data 的可能副本。由于库使用HttpListener,您可以使用ServicePointManager 来控制它。或者,虽然不理想,但您可以通过发送额外数据来强制解决问题。或者,您可以忍受延迟(您的帖子不清楚为什么 200 毫秒的延迟实际上是一个问题……通常不会这样)。

标签: c# algorithm tcp servicestack nagle


【解决方案1】:

我认为您在 Update UseNagleAlgorithm = false 中提供了答案应该可以解决此问题。但要小心,因为ServicePointManager.UseNagleAlgorithm = false; 是一个全局设置,这意味着它将为您的所有端点以及整个应用程序域中的所有请求关闭此算法。当您使用混合大小的请求调用多个服务端点(通常是这种情况)时,它会反击。所以你应该考虑只为一个特定的 ServicePoint 设置它,你可以通过以下方式获取它:

ServicePoint sp = ServicePointManager.FindServicePoint(<uri>);
sp.UseNagleAlgorithm = false;

而不是全局设置

这是一篇关于它的文章:https://blogs.msdn.microsoft.com/windowsazurestorage/2010/06/25/nagles-algorithm-is-not-friendly-towards-small-requests/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-24
    • 2014-07-11
    • 2020-07-10
    • 1970-01-01
    • 2016-02-08
    • 2016-01-22
    • 2019-10-07
    相关资源
    最近更新 更多