【问题标题】:How slow are TCP sockets compared to named pipes on Windows for localhost IPC?与 Windows 上本地 IPC 的命名管道相比,TCP 套接字有多慢?
【发布时间】:2012-06-08 00:14:09
【问题描述】:

我正在开发一个 TCP 代理,放在一个 TCP 服务前面,该服务应该处理来自外部 Internet 的 500 到 1000 个活动连接。

代理与服务在同一台机器上运行,并且大部分是透明的。该服务在很大程度上不知道代理,唯一的例外是通知客户端的真实远程 IP 地址。

这意味着,对于每个入站打开的 TCP 套接字,服务器上还有两个套接字:代理中的第二个套接字,以及代理后面的真实服务上的一个。

两个代理套接字上的发送和接收窗口大小设置为 1024 字节。

这对性能有何影响?这个配置有多慢?我应该努力改变服务以使用命名管道(或其他 IPC 机制),还是 localhost TCP 套接字在很大程度上是一个高效的 IPC?

这两个应用程序的合并不是一个选项。现在我们被两个进程配置卡住了。

编辑:在同一硬件上拥有两个独立进程的原因是 100% 经济性。我们只有一台服务器,我们不打算获得更多(没有钱)。

TCP 服务是 Visual Basic 6 中的旧版软件,其发展超出了我们的预期。代理是 C++。我们没有时间、金钱和人力来重写 VB6 代码并将其迁移到现代编程环境。

代理是我们尝试缓解服务上的特定性能问题,我们不时收到DDoS attack

代理是开源的,and here is the project source code

【问题讨论】:

  • 主机内 TCP 连接将在任何值得其盐的现代网络堆栈上尽可能高效地实现(阅读:作为双向本地管道,或等效的东西),所以我如果在此用例中 TCP 和命名管道之间存在明显的性能差异,我会感到惊讶(并且对 Microsoft 有点失望)。
  • @JeremyFriesner 我同意你的观点,我想假设“Windows Server 2008”就是这种情况。

标签: windows performance sockets named-pipes


【解决方案1】:

我知道这个话题很老了,但对我来说仍然很重要,也许其他人将来也会关注这个。

我在 Excel (VBA) 和同一台机器上的另一个进程之间实现了 IPC,既通过 TCP 连接,也通过命名管道。

在快速性能测试中,我从客户端 (Excel) 向服务器(不是 Excel)提交了一条包含 26 个字节的消息,并等待来自其他进程的回复消息(在示例中由 12 个字节组成) . 我在一个循环中执行了很多次,并测量了平均执行时间。

使用 localhost 上的 TCP(Windows 7,无快速路径),一次“对话”(请求+回复)大约需要 300-350 微秒。尤其是发送数据非常慢(通过 TCP 发送 26 个字节大约需要 200 微秒)。 使用命名管道,一次对话平均需要大约 60 微秒 - 所以要快很多。

我不完全确定为什么差异如此之大。我测试的企业环境有严格的防火墙、包检查等等,所以我认为这可能是由于即使是基于 localhost 的 TCP 连接也通过了安全措施显着减慢了它,而命名管道的可能没有。

TL:DR:在我的例子中,命名管道比 TCP 小包快 5-6 倍(还没有测试过更大的包)

【讨论】:

  • 有趣,+1,但是当您发送大量像这样的小数据包时,开销(例如内核转换)可能占主导地位 - 所以结果很大程度上取决于诸如您正在使用的 API 函数,无论您选择了异步还是同步 I/O,还可能是外部因素,例如安装了哪些防病毒软件以及是否实施了 Meltdown 缓解措施。我想底线是每个人都需要描述自己的场景。
  • ...如果您真的需要尽可能最好的性能,您可能应该使用共享内存。 :-)
  • @HarryJohnston 确实;在我的情况下,同步 I/O(我认为异步在我的特定情况下没有帮助,不能在 VBA 中使用那么多)。例如。仅在调用 WinSock 的“发送”函数上花费了 200 微秒。至于共享内存-同意,我也尝试过,但还没有成功,尝试使用小缓冲区但有一些奇怪的效果,不确定是否由于缺乏 VBA 易失性读取功能.. 但可能稍后回来试试这个
【解决方案2】:

对于稍后阅读本文的任何人,我想添加一些回答原始问题的发现。

对于我们正在开发的实用程序,我们有一个网络类,可以使用命名管道或具有相同调用的 TCP。

这是我们测试系统上的典型环回文件传输:

TCP/IP 传输时间:2.5 秒
命名管道传输时间:3.1 秒

现在,如果您离开机器并连接到网络上的远程计算机,命名管道的性能会更差:

TCP/IP 传输时间:12 秒
命名管道传输时间:2.5 分钟(是的分钟!)

我意识到这只是一个系统(Windows 7),但我认为它是命名管道有多慢的一个很好的指标......而且似乎 TCP 是要走的路。

【讨论】:

  • 对远程命名管道的评论是问题的一个红鲱鱼,这是关于相同的机器场景。命名管道实际上是同一机器对象,由内核通过共享内存实现。远程命名管道实际上是“真正的命名管道”+ SMB + 用于通过 SMB 将通信映射到管道名称端点的专有协议。在这些附加部分中可能会发生各种影响性能的事情,这与“真正的”命名管道性能无关。
  • 在哪里声明“命名管道实际上是同一机器对象,由内核通过共享内存实现。”?
  • 文件大小是多少?多大的包在哪里?什么样的管道/插座? IOCP?
  • 高度事务性的数据交换,比如远程过程调用呢?管道有冲洗,而插座没有。所以我假设 NP 在本地机器上要好得多。
【解决方案3】:

这将是相同的(或至少没有明显不同)。 Winsock 足够聪明,可以知道它是否正在与同一主机上的套接字通信,在这种情况下,它将使 IP 以下的几乎所有内容短路并直接将数据复制到缓冲区。就命名管道与套接字而言,如果您将来可能需要能够与不同的机器通信,请选择套接字。如果您知道自己永远不需要这样做,请选择您的开发人员最熟悉或最熟悉的那个。

【讨论】:

  • 确定吗?你有什么参考吗?我想环回连接预计将流经网络接口并通过网络堆栈。这样他们就可以成为防火墙过滤规则的对象。即,“如果 SYN 数据包从 locahost 到 localhost 到端口 XYZ,则丢弃该数据包”。 Windows 确实有一些(隐藏的)防火墙。
  • @vz0:根据我的经验,Windows 防火墙从不过滤发往本地主机的数据包。例如,您可以运行网络服务器并在本地计算机上使用它,而无需更改防火墙规则。
  • 我的参考是我曾经在 Windows 网络上为 Microsoft 工作。即便如此,防火墙在 IP 层及更高层上运行,而我在说的是,winsock 正在短路下面的所有东西。没有理由不能将防火墙规则应用于环回(除了明显的“你为什么要打扰?”)。环回上的东西仍然通过网络堆栈,而不是整个网络堆栈,剩余的开销可以忽略不计,除非您同时执行数万次,否则它是微不足道的。
  • @JeffTucker 你还觉得套接字是要走的路吗?我遇到了一些问题,很感谢您的想法。请看stackoverflow.com/questions/26653624/…
  • @JeffTucker 与命名管道相比,您认为the socket loopback fast path 对性能有何影响?
【解决方案4】:

在您描述的场景中,本地 TCP 连接不太可能成为瓶颈。当然,它会引入一些开销,但这应该可以忽略不计,除非你的 CPU 已经很热了。

推测一下,如果您的服务器的 CPU 使用率通常低于 50% 左右(使用代理),则不必担心与本地 TCP 连接相关的开销最小化。

如果 CPU 使用率经常超过 80%,您可能应该进行一些分析。我将首先比较代理到位时的 CPU 负载(或者,如果可以有意义地测量它,性能更好)。除非代理正在执行一些复杂的处理,否则与额外 TCP 连接相关的开销可能是代理引入的总开销的很大一部分,因此这应该至少为您提供一个数量级的估计值d 通过使用更有效的 IPC 形式获得收益。

【讨论】:

    【解决方案5】:

    在同一台机器上有代理的原因是什么,只是好奇?

    无论如何:

    IPC有几种方法,TCP/IP,命名管道在速度和复杂度上是相当的。如果您真的想要可扩展且几乎没有开销的东西:使用共享内存。最好与无锁算法结合使用以推进指针(或为每个读取器(代理/服务)和写入器(服务/代理)使用一个缓冲区)。

    【讨论】:

    • 我们只有一台服务器,不能在不同的机器上运行程序。
    • @vz0:这个数字……好吧。 Dan 说的是:如果您使用 TCP/IP 进行 IPC,您还可以稍后在需要时跨越机器边界;否则共享内存是最快的。
    • 命名管道是在 Windows 上使用 共享内存 (MMF) 实现的,所以这一点还没有实际意义 :)
    • @STATUS_ACCESS_DENIED:不,不是!您仍然有内存缓冲区管理的开销,进入内核并返回两个进程和使用的同步。使用自己的缓冲区时,速度会更快,尤其是在使用非常小的消息(例如 100 字节或更少)时。
    • @Ritsaert Hornstra:请准确地说:它不是通过 MMF 实现的(如果这是您的主张,请提供可靠的来源)或者开销大于原始 MMF?很明显,开销存在并且大于没有开销。我什至不会争论。
    【解决方案6】:

    http://msdn.microsoft.com/en-us/library/aa178138(v=sql.80).aspx

    让我为你总结一下。如果您担心性能,请使用 TCP/IP。但是,如果您有一个非常快的网络并且您不担心性能,那么命名管道将是“整洁”的,因为它可能会为您节省一些代码。

    更不用说,如果您坚持使用 TCP,那么您将拥有可以扩展的东西,甚至在时机成熟时进行负载平衡。

    干杯,

    【讨论】:

    • 谢谢。但是,那篇文章讨论了网络上的套接字与命名管道,用于不同机器上的 IPC。我的程序永远不会在单独的硬件上运行或相互通信。
    • 对链接的 MSDN 文章的更中肯的总结将单独列出此部分:“如果服务器应用程序在运行 Microsoft® SQL Server™ 2000 实例的计算机上本地运行,则本地命名管道协议是一个选项。本地命名管道在内核模式下运行并且非常快”。对于同一台机器上的 IPC,命名管道比 TCP/IP 更快。
    • @Dan,IPC 不应该比 TCP 快吗?
    • 现在可能......但早期版本的 Windows 肯定不是这种情况。例如 Vista,这是我的主要信息来源。
    猜你喜欢
    • 2010-12-17
    • 2010-11-17
    • 2011-09-23
    • 2021-09-21
    • 1970-01-01
    • 1970-01-01
    • 2010-10-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多