14

我有现在通过 TCP 通信的客户端和服务器程序。我正在尝试使用 POSIX 消息队列(当然,在客户端和服务器在同一台机器上的情况下)。我希望它能提高性能(特别是通过减少延迟)。

我已经解决了大部分问题,但不确定一件事:如何建立“连接”。服务器同时接受来自多个客户端的连接,所以我很想模拟 TCP 连接建立过程,如下所示:

  1. 服务器打开一个具有已知名称的队列并连续读取它(它可以select(2)与 TCP 一起使用)。
  2. 客户端打开三个队列:两个具有任意名称(包括一些唯一性,例如 PID 以避免冲突),一个具有服务器使用的众所周知的名称。
  3. 客户端向服务器的队列发布一条“连接”消息,包括客户端的队列名称(一个指定用于客户端到服务器的流量,另一个用于相反的流量)。
  4. 服务器打开客户端连接消息中指定的队列,并开始从客户端到服务器的队列中读取(选择)。
  5. 客户端使用众所周知的名称关闭服务器队列。双向通信使用客户端命名的两个队列(每个方向一个)进行。

您可能会看到该方案与常见的 TCP 方法有何相似之处,这绝非偶然。但是,我想知道:

  1. 你能想出更好的方法吗?
  2. 你看到我的方法有什么潜在的问题吗?
  3. 您是否还有其他想法,包括在同一台机器上使用消息队列而不是 TCP 是否会真正提高性能(延迟)?

请记住,我之前没有使用过 POSIX 消息队列(我之前确实使用过 IBM WebSphere MQ,但那是相当不同的)。平台是Linux。

4

6 回答 6

7
  1. 你能想出更好的方法吗?

    也许看看fifos(又名命名管道)。它们就像网络套接字,但用于本地机器。它们是单向的,因此您可能需要创建两个,每个方向一个。您的问题确实没有任何理由说明您为什么要专门进行此更改。使用套接字进行进程处理通信没有任何问题。它们是双向的、高效的、受到广泛支持的,并且确实让您可以自由地在以后分离机器之间的进程。

  2. 你看到我的方法有什么潜在的问题吗?

    System V 消息队列和 fifo 命名管道都非常好。Fifo 管道就像常规管道一样,因此您可以通过最少的代码更改来读取()和写入()。System V 消息队列需要将数据放入结构中并调用 msgsnd()。然而,任何一种方法都可以。

  3. 您是否还有其他想法,包括在同一台机器上使用消息队列而不是 TCP 是否会真正提高性能(延迟)?

    我的其他想法是,正如您所说,您需要开发一种技术,以便每个客户都有一个唯一的标识符。一种方法是将pid添加到您传递的结构中,或者在开始时与父/主协商一个唯一的ID。要注意的另一件事是 System V 消息队列的好处是您可以侦听“选择性”消息,因此您可以理想地使用从服务器到所有客户端的一个队列,每个客户端等待不同的消息。

    我不知道哪种技术可以为您的软件提供最佳吞吐量。确实可能不值得使用 System V 消息队列,但只有您可以做出决定。

菲尔米蒂

于 2009-01-03T23:40:59.840 回答
6

我最终基本上按照我的描述实现了它,并进行了一些改进:

  • 在第 2 步中,我使用 GUID 作为队列名称,而不是合并客户端的 PID。
  • 在第 4 步中,我添加了从服务器向客户端发送“接受”消息。
  • 当任何一方希望结束通信时,它会发送一个“断开连接”消息。

握手比 TCP 简单,但似乎足够了。

至于延迟:它要好得多。在同一台机器上使用 POSIX 消息队列而不是 TCP 大约减少了 75% 的延迟。我的消息每条大约 100 个字节。

于 2009-01-28T04:03:14.200 回答
3

我比较了 posix MQ 和一对 TCP/IP 套接字的性能。

演示程序有两个线程,一个用于写入,另一个用于读取。

结果是posix MQ更快,

  • MQ 460000 tps
  • 套接字对 400000 tps
于 2012-05-03T02:44:07.933 回答
1

我遇到过类似的问题,我开发实时应用程序,需要具有类似于套接字功能和最小延迟的 IPC 技术。

您是否仅将基于 POSIX-MQ 的解决方案与 UNIX 本地套接字或 TCP 套接字进行了比较?

谢谢

于 2009-11-11T09:21:58.807 回答
0

当 select() 不适用于消息队列时,您是如何做到这一点的?什么是 Sys V 或 POSIX?当 PID 保证是唯一的并且是较小的存储(整数)时,为什么还要花额外的精力来创建 GUID 到 PID 查找表?

/哭泣/

于 2009-02-14T22:17:36.517 回答
-1

您也可以在驻留在不同机器上的程序中使用 Message Queues for IPC,在这种情况下您可以使用 ZeroMQ( http://www.zeromq.org ) 或其他消息队列 API,我也建议您考虑它们并测试他们也是。

于 2013-04-05T10:20:36.260 回答