14

我正在从事一个项目,该项目涉及几个 C++ 程序,每个程序都接受输入并生成输出。数据(几十到几百字节,可能是 JSON)本质上是(异步地)向一个方向流动,并且程序需要位于 LAN 周围的不同 Linux 计算机上。

由于数据只向一个方向流动,我认为我不需要像 HTTP 这样的事务模型。我认为消息队列模型(即发即弃)最有意义,并且应该简化每个程序的逻辑。仅注意消息已成功添加到远程队列可能就足够了。

我正在寻找的是有关如何在 C 或 C++ 中实现此消息队列的建议。POSIXBoost消息队列似乎仅限于单个主机,RabbitMQ似乎对 C/C++ 的支持较弱,而MQ4CPP似乎不足以支持关键业务角色。我错了吗?Boost ASIOACE或自己编写套接字代码呢?我期待您的建议。

4

6 回答 6

12

在简单的消息传递支持方面,ZeroMQ 很难被击败。它在许多语言绑定中可用,并支持从简单的发送和接收到发布/订阅、扇出甚至消息传递管道的所有内容。该代码也很容易消化,并且可以很容易地在模式之间切换。

查看他们的Weather Update Server 示例(使用 20 种奇怪的语言)显示了创建发布/订阅设置是多么容易:

zmq::context_t context (1);
zmq::socket_t publisher (context, ZMQ_PUB);
publisher.bind("tcp://*:5556");
publisher.bind("ipc://weather.ipc");

while(1) {
    //  Send message to all subscribers
    zmq::message_t message(20);
    snprintf ((char *) message.data(), 20 ,
        "%05d %d %d", zipcode, temperature, relhumidity);
    publisher.send(message);
}

我已经在一些混合的 C# 和 Python 进程上使用了它,没有太多麻烦。

于 2012-05-05T02:01:54.657 回答
2

就个人而言,如果我理解这个问题,我认为您应该使用较低级别的 TCP 连接。它具有您想要的所有保证交付,并且具有相当好的 Berkley Sockets API。我发现如果你愿意实现一个非常简单的协议(例如,四字节的 NBO 消息长度,n字节的数据),你可以得到非常简单、非常可定制和非常简单的。如果你这样做,你也(如前所述)得到很好的 C 支持(这意味着 C++ 支持,虽然东西不在类和方法中)。套接字代码也很简单,它们具有异步 IO,带有用于 Linux/UNIX/POSIX IO 功能的标准异步标志(这是其他好处之一,如果您对 POSIX 编程有所了解,那么您基本上知道套接字 API) .

学习套接字 API 的最佳资源之一是:

  • Beej 的网络编程指南:http ://beej.us/guide/bgnet/ ,如果除了细节之外还需要整体编程模型,这非常好
  • 手册页:如果您只需要函数签名、返回值和参数,这些就是您所需要的。我发现 Linux 的写得很好而且很有用(证明:看看我的控制台:man, man, man, man, man, make, man, ...)

此外,为了使数据网络可发送,如果您的数据是 JSON,您无需担心。因为 JSON 只是 ASCII(或 UTF-8),所以它可以通过网络以原始形式发送,只有一个长度标头。除非您尝试发送复杂的二进制文件,否则这应该是完美的(如果您需要复杂的二进制文件,请查看序列化或准备很多Segmentation Fault)。


此外,如果您使用套接字路径,您可能想要使用 TCP。尽管 UDP 会为您提供单向方面,但使其可靠这一事实使您的自制解决方案与 Linux 内核提供的顶级 TCP 相抗衡,但 TCP 是一个明显的选择。

于 2012-05-03T23:03:14.163 回答
2

RabbitMQ 只是AMQP的一种实现。您可能想要研究Apache Qpid或其他可能对 C/C++ 更友好的变体。尽管我没有第一手经验,但有一个用于 C 的libamqp 。我不知道您的确切要求是什么,但正确实施的 AMQP 具有工业实力,并且应该比您在短时间内手工构建的任何东西都要快几个数量级且更稳定。

于 2012-05-04T00:46:49.577 回答
1

另一个消息传递解决方案是 ICE ( http://www.zeroc.com/ )。它是多平台、多语言的。它更多地使用 RPC 方法。

于 2012-05-04T16:40:13.257 回答
1

我正在为类似的应用程序使用 Boost 序列化和套接字发送。您可以在此处找到序列化的示例:

http://code.google.com/p/cloudobserver/wiki/TutoriaslBoostSerialization

在这个页面上:

http://www.boost.org/doc/libs/1_38_0/doc/html/boost_asio/examples.html

在序列化下,您将找到有关如何制作服务器和客户端的示例。在特定端口上创建一个服务器,您可以在多台计算机上生成多个可以与该端口通信的客户端。

使用 boost 序列化的缺点是,如果你有一个简单的数据结构要序列化,它会产生很大的开销,但它确实很容易。

于 2012-05-03T22:55:14.697 回答
1

另一个推荐是分布式框架OpenCL。文档The OpenCL C++ Wrapper for API提供了有关该库的更多信息。特别是,API 函数cl::CommandQueue对于在网络设置中的设备上创建队列可能很有意义。

于 2012-05-03T23:11:50.923 回答