(编辑试图更好地解释)
我们有一个用C ++编写的Win32代理。它需要定期将信息发布到服务器。 必须支持断开连接的操作。即:客户端并不总是与服务器建立连接。
注意:这适用于在台式机上运行的代理之间的通信,以便与在企业中某处运行的服务器进行通信。
这意味着要发送到服务器的消息必须排队(以便在连接可用后发送)。
我们目前使用内部系统将消息排队为磁盘上的单个文件,并使用HTTP POST将它们发送到服务器。
它开始显示它的年龄,我想在考虑更新它之前研究替代品。
默认情况下,它必须在Windows XP SP2,Windows Vista和Windows 7上可用,或者必须简单包含在我们的安装程序中。 此产品将(由管理员)安装在几十万台PC上。他们可能会使用像Microsoft SMS或ConfigMgr这样的东西。在这种情况下,“轻浮”的先决条件是不受欢迎的。这意味着,除非客户端代码(或可再发行组件)可以包含在我们的安装程序中,否则管理员将不满意。这使得MSMQ特别难卖,因为默认情况下它没有安装XP。
在Win32上使用C ++必须相对简单。 我们的客户端是一个非托管的C ++ Win32应用程序。客户端没有.NET或Java。
答案 0 :(得分:3)
您当前的解决方案如何显示其年龄?
我会把逻辑推到后端,让客户端非常简单。
消息只是存储在文件系统中。让客户端写入c:/ queue / {uuid} .tmp。写入文件时,将其重命名为c:/ queue / {uuid} .msg。这使得将消息写入客户端上的队列“atomic”。
C ++线程唤醒,扫描c:\ queue中的“* .msg”文件,如果找到一个,则检查服务器,然后HTTP将消息发送给它。当它从服务器收到200状态(即它已收到消息)时,它可以删除该文件。它只扫描* .msg文件。 * .tmp文件仍然被写入,并且您在尝试发送仍在写入的msg文件时遇到竞争条件。这就是.tmp的重命名。我还建议按创建日期进行扫描,以便尽早发送消息。
您的服务器收到消息,在这里它可以进行任何必要的欺骗检查。将此负担推到服务器上以集中它。您可以简单地为每条消息记录每个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