我最近创建了一个错误管理器,用于从我们网络上的客户端获取记录错误,并将它们放入MSMQ进行处理。我在服务器上运行一个单独的Windows服务来从队列中挑选项目并将它们推送到数据库中。
当我写它并测试它时,一切都很好;但是我忽略了考虑到在部署时,有100个客户端都发送到公共队列可能不是高性能,最好的情况,最坏的情况可能会发生各种冲突,在我看来。
我现在的想法是使用WCF服务来引导MSMQ并让每个人都通过它。逻辑是,在那一点上,我可以使用一些锁定,等等。如果我使用服务,我认为我可以使用私人队列而不是公共队列,这也会更快。
我不确定的是,我是否在思考它? MSMQ非常强大,我认为这些方法是线程安全的。我应该不管它,看看会发生什么?如果我确实投入了这项服务,我需要管理多少管理?
答案 0 :(得分:1)
我最近创建了一个错误管理器来从客户端获取记录错误 在我们的网络上并将它们放入MSMQ进行处理
我假设您正在使用System.Messaging吗?如果是这样,你的方法就没有任何错误。
有100个客户端都发送到公共队列可能不是 高性能
MSMQ从下到上设计用于处理高负载。根据各个消息的大小和机器的存储阈值,队列可以容纳10万条消息,而不会对性能产生明显的影响。
因为"发送"在MSMQ中涉及每台机器上的队列管理器在传输之前在本地写消息(在store and forward消息传递模式中),几乎没有机会发生冲突"或任何其他形式的争用;如果发件人无法发送消息,则只需发送"发送"它到一个临时的本地队列,然后实际的传输发生在后台,并由容错和非常可靠的msmq协议调解。
我现在的想法是使用WCF服务前进MSMQ并制作 每个人都经历过
如果你从零开始,这将是一个有效的选择。正如另一张海报所述,WCF通过消除使用System.Messaging的必要性,确实隐藏了一些 msmq-voodoo 。但是,您已经编写了代码,因此我发现公开netMsmqBinding
端点的好处不大。
如果我使用服务,我想我可以使用私人队列 而不是公开的
据我所知,根据您的描述,在您当前的场景中没有什么可以阻止您使用私人队列。事实上,我建议总是使用私人队列,因为它们更简单。
如果我确实投入了这项服务,我需要管理多少 在哪里?
使用wcf服务会增加管理开销。因为您使用WCF堆栈包装发送 - 接收的每一端,所以有更多代码要启动,因此可能会失败。如果未启用完整服务日志记录,则WCF堆栈异常很难进行故障排除。
编辑 - 回应评论
我认为对于一个私人队列,你必须真正写出来自 队列所在的机器,这在联网中不起作用 环境
不真实的。无论队列是本地队列还是远程队列,MSMQ都支持对任何专用队列进行事务性读取和写入。
这是因为消息在msmq中从一台机器发送到另一台机器的任何时间,无论队列地址如何,都会发生以下情况:
如果您使用的是交易,则上述步骤将包含3个不同的交易。
要记住的事情:在不同机器上的队列之间交换消息的最安全的范例是发送远程,读取本地。
这意味着当您发送消息时,您将指示msmq发送到远程队列地址。但是,当有人向你发送信息时,他们必须这样做。因此,您最终只能从本地队列中读取,并且只能发送到远程队列。
通过这种方式,您可以获得最可靠的消息传递设置,因为在读取时,本地队列始终可用。
试试吧!我已经使用msmq进行跨机器通信近10年了,而且我从未使用过公共队列。我甚至都不知道他们的目标是什么!
答案 1 :(得分:0)
我会公开一个WCF“IsOneWay”方法。 然后在IIS中托管您的WCF。
IsOneWay将连接到MSMQ。
这样......你拥有IIS托管的强大功能。您可以公开所需的任何端点。 但最终请求进入了MSMQ。
其中一个原因是使用wcf轻松使用msmq。编写并使用msmq“pre-wcf”后,我发现代码(从队列中拉出消息和错误处理)是困难和有问题的。仅这一点就会让我转向WCF托管。
正如您所提到的,本地队列周围的安全性更容易处理。
底线,让WCF为你处理msmq-voodoo。
以下简单示例。
[ServiceContract]
public interface IMyControllerController
{
[OperationContract(IsOneWay = true)]
void SubmitRequest( MyObject obj );
}
http://msdn.microsoft.com/en-us/library/ms733035%28v=vs.110%29.aspx
What happens in WCF to methods with IsOneWay=true at application termination