2012-05-03 30 views
9

我正在研究一个涉及多个C++程序的项目,每个C++程序都需要输入并生成输出。数据(几十到几百个字节,可能是JSON)基本上以一个方向流动(异步),程序需要位于局域网内的不同Linux计算机上。针对C/C++远程消息队列的建议

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

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

+2

[ZeroMQ很不错](http://www.zeromq.org)。 – user7116

+0

大家都很好的答案,但我真的很喜欢ZeroMQ的简单性。如果@sixlettervariables将它作为答案,我会接受它。 –

回答

8

在简单消息传递支持方面,ZeroMQ is hard to beat。它提供了许多语言绑定,并支持从简单发送和接收到发布/订阅,扇出或甚至消息管道的所有内容。该代码也很容易消化,并且使得在模式之间切换非常容易。在他们Weather Update Server sample(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的过程,没有什么麻烦。

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序列化的缺点是,如果你有一个简单的数据结构被序列化,它有很大的开销,但它确实很容易。

2

就个人而言,如果我理解这个问题,我认为你应该使用一个较低级别的TCP连接。它拥有你想要的所有保证交付,并且具有相当不错的Berkley套接字API。我发现如果你愿意实现一个非常简单的协议(例如4字节的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是一个明显的选择。

1

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

2

RabbitMQ只是AMQP的一个实现。您可能想要调查Apache Qpid或其他可能更适合C/C++的变体。 C有一个libamqp,虽然我没有第一手的经验。我不清楚你的要求是什么,但是正确实施的AMQP是工业实力,应该比在短时间内手工制造的任何东西都快几个数量级。

1

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

+0

虽然它是一款出色的产品,但[ICE是GPLed](http://www.zeroc.com/licensing.html)。除非您的代码是GPL或者愿意支付商业许可证,否则我会避开它。 – Void