消息队列解决方案?

时间:2010-01-05 10:43:24

标签: c++ winapi message-queue

(编辑试图更好地解释)

我们有一个用C ++编写的Win32代理。它需要定期将信息发布到服务器。 必须支持断开连接的操作。即:客户端并不总是与服务器建立连接。

注意:这适用于在台式机上运行的代理之间的通信,以便与在企业中某处运行的服务器进行通信。

这意味着要发送到服务器的消息必须排队(以便在连接可用后发送)。

我们目前使用内部系统将消息排队为磁盘上的单个文件,并使用HTTP POST将它们发送到服务器。

它开始显示它的年龄,我想在考虑更新它之前研究替代品。

  1. 默认情况下,它必须在Windows XP SP2,Windows Vista和Windows 7上可用,或者必须简单包含在我们的安装程序中。 此产品将(由管理员)安装在几十万台PC上。他们可能会使用像Microsoft SMS或ConfigMgr这样的东西。在这种情况下,“轻浮”的先决条件是不受欢迎的。这意味着,除非客户端代码(或可再发行组件)可以包含在我们的安装程序中,否则管理员将不满意。这使得MSMQ特别难卖,因为默认情况下它没有安装XP。

  2. 在Win32上使用C ++必须相对简单。 我们的客户端是一个非托管的C ++ Win32应用程序。客户端没有.NET或Java。

  3. 传输应为HTTP或HTTPS。 即:它必须轻松通过防火墙;没有RPC或DCOM。
  4. 它应该相对可靠,重试等。防止重放是必须的。
  5. 它必须是可扩展的 - 有很多流量。每个消息对服务器的影响应该是最小的。
  6. 服务器端是C#,目前使用ASP.NET实现简单的HTTP POST机制。
  7. (有点奇怪的)。它必须支持客户端内存中队列,以便我们可以避免启动硬盘。它必须允许定期冲洗磁盘。
  8. 必须适合在专有产品中使用(即没有GPL等)。

4 个答案:

答案 0 :(得分:3)

您当前的解决方案如何显示其年龄?

我会把逻辑推到后端,让客户端非常简单。

  1. 消息只是存储在文件系统中。让客户端写入c:/ queue / {uuid} .tmp。写入文件时,将其重命名为c:/ queue / {uuid} .msg。这使得将消息写入客户端上的队列“atomic”。

  2. C ++线程唤醒,扫描c:\ queue中的“* .msg”文件,如果找到一个,则检查服务器,然后HTTP将消息发送给它。当它从服务器收到200状态(即它已收到消息)时,它可以删除该文件。它只扫描* .msg文件。 * .tmp文件仍然被写入,并且您在尝试发送仍在写入的msg文件时遇到竞争条件。这就是.tmp的重命名。我还建议按创建日期进行扫描,以便尽早发送消息。

  3. 您的服务器收到消息,在这里它可以进行任何必要的欺骗检查。将此负担推到服务器上以集中它。您可以简单地为每条消息记录每个uuid以进行重复消除。如果该列表太长(我不知道您的流量),也许您可​​以剔除超过30天的项目(我也不知道您的客户可以保持多长时间离线)。

    < / LI>

    这个系统很简单,但非常强大。如果文件发送线程出错,它将只是尝试下次发送文件。您应该获取重复消息的唯一时间是在客户端从服务器获取200 ack和删除文件之间的窗口中。如果客户端在此时关闭或崩溃,您将拥有一个已发送但未从队列中删除的文件。

    如果您的客户稳定,这是一个非常低的风险。通过基于消息ID的欺骗检查,您可以以一些簿记为代价来缓解这种情况,但维护一份uuids并不是一件令人畏惧的事情,但这又取决于您的消息量和其他性能要求。

    您被允许“离线”工作的事实表明您的绝对消息传递性能有一些“松弛”。

答案 1 :(得分:1)

说实话,列出的要求没有多大意义,并且表明您在MQ学习方面还有很长的路要走。鉴于此,如果您不想使用MSMQ(可能是Windows上最简单的 - 但有[IMO严重]限制),那么您应该查看:

qpid - 体面使用AMQP标准

zeromq - (最好的,IMO,技术上但也需要最熟悉MQ技术)

我也推荐rabbitmq,但那是一个Erlang服务器,最后我看起来没有可用的C或C ++库。不过,如果你正在购买MQ,请看一下......

[编辑]

我已经回去重新阅读您的要求以及您的一些评论,并为您思考,也许客户端MQ - &gt;服务器不是你最好的选择。我可能会考虑让你的客户 - &gt;服务器操作是HTTP POST或SOAP,并允许HTTP端点依次在MQ后端上发送队列消息。 IOW,将MQ客户端抽象为您可以更好地控制的架构。然后你的C ++客户端就是HTTP(简单),而你的HTTP服务(可能是C#/ .Net来自你的评论)可以与你选择的任何MQ后端进行交互。如果您的所有HTTP端点都是生成的MQ消息,那么它将非常轻量级,并且可以扩展所有传统的负载平衡技术。

答案 2 :(得分:0)

上次我想做任何消息传递时都使用了C#和MSMQ。有一些MSMQ库可以很容易地使用MSMQ。它可以在你的服务器上免费安装,直到今天都不会丢失消息。它独自处理重启等。这是美丽的事情,每天处理100,000条消息。

我不确定你为什么要排除MSMQ而我没有得到第2点。

对于队列而言,我们只是将记录数据转储到数据库表中,而另一个进程会定期将行从表中提取出来。

答案 3 :(得分:0)

如何使用.NET Framework 4.0中的异步代理库。它仍然是测试版。

http://msdn.microsoft.com/en-us/library/dd492627(VS.100).aspx