针对 C/C++ 远程消息队列的建议

Recommendations for C/C++ remote message queues

本文关键字:消息 队列 C++ 程消息 针对      更新时间:2023-10-16

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

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

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

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

查看他们的天气更新服务器示例(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 流程中使用它,没有太多麻烦。

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

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

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

此外,为了使数据网络可发送,如果您的数据是JSON,则无需担心。由于 JSON 只是 ASCII(或 UTF-8(,因此可以通过网络发送原始数据,只需一个长度标头。除非您尝试在二进制中发送复杂的东西,否则这应该是完美的(如果您需要二进制复杂,请查看序列化或准备大量Segmentation Fault(。


此外,如果您使用套接字路径,您可能想要使用 TCP。尽管UDP将为您提供单向方面,但使其可靠的事实就是将您的自制解决方案与Linux内核提供的顶级TCP进行对比,TCP是一个显而易见的选择。

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

我正在为类似的应用程序使用 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 序列化的缺点是,如果要序列化一个简单的数据结构,它会有很大的开销,但它确实使它变得容易。

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

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