针对 C/C++ 远程消息队列的建议
Recommendations for C/C++ remote message queues
我正在做一个项目,该项目涉及多个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的写得很好,很有用(证明:看看我的控制台:
man
,man
,man
,man
,man
,make
,man
,...
此外,为了使数据网络可发送,如果您的数据是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 方法。
- boost::进程间消息队列引发错误
- 避免使用 boost::进程间::消息队列创建文件
- 提升消息队列 跨两个进程未接收
- 可以将Boost消息队列文件重定向到用户指定的位置
- 使用加速进程间创建消息队列 - 内存访问冲突
- 如何检查提升消息队列是否存在
- Win32 消息队列在使用 OpenGL 渲染时被淹没
- 在尝试使用boost时断言.跨很多过程中的互动消息队列
- GetMessage/PeekMessage - 删除消息队列中的所有消息
- IPC Unix 消息队列线程安全吗?
- 在.c文件接收函数中使用Linux中的MSGGET创建消息队列未实现错误
- boost消息队列线程安全和进程安全吗?
- 为什么我的无锁消息队列段错误:(?
- 在控制台应用程序中处理空的windows消息队列
- 关于在这种情况下消息队列与共享内存的适用性或适用性
- boost::进程间消息队列创建时的竞争条件
- 从内存转储中查找线程消息队列中的消息
- win32消息泵,do dispatchMessage()处理整个消息队列或仅仅是顶部消息
- 如何使用Boost进程间消息队列for Windows
- 来自另一个线程的 SendMessage() 调用是否将消息发布到消息队列