multithreading - 在具有多个用户的网络上使用 MSMQ 与在本地使用一个用户

标签 multithreading wcf architecture msmq distributed-computing

我最近创建了一个错误管理器,用于从我们网络上的客户端记录错误并将它们放入 MSMQ 进行处理。我在服务器上运行了一个单独的 Windows 服务,用于从队列中挑选项目并将它们推送到数据库中。

当我编写并测试它时,一切都很好;但是我忽略了考虑,在部署时,让 100 个客户端全部发送到公共(public)队列可能性能不佳,最好的情况,最坏的情况可能会出现各种冲突,在我看来。

我现在的想法是在 MSMQ 前面使用 WCF 服务并让每个人都经历它。逻辑是那时我可以使用一些锁定等。如果我使用服务,我认为我可以使用私有(private)队列而不是公共(public)队列,这也会更快。

我不确定的是,我是不是想多了? MSMQ 非常健壮,我认为这些方法是线程安全的。我是不是应该不管它,看看会发生什么?如果我确实提供了服务,我需要进行多少管理?

最佳答案

I recently created an error manager to take logged errors from clients on our network and put them into an MSMQ for processing



我假设您为此使用 System.Messaging?如果是这样,您的方法没有任何问题。

having 100 clients all sending to a public queue might not be performant



MSMQ 自下而上设计用于处理高负载。根据单个消息的大小和机器的存储阈值,一个队列可以容纳数千条消息,而不会对性能产生任何明显的影响。

因为 MSMQ 中的“发送”涉及每台机器上的队列管理器在传输之前在本地写入消息(在 store and forward 消息传递模式中),所以几乎不会发生“冲突”或任何其他形式的争用;如果发送方无法传输消息,它只是将消息“发送”到临时本地队列,然后实际传输发生在后台,并由容错且非常可靠的 msmq 协议(protocol)进行调解。

My thought right now is to front the MSMQ with a WCF service and make everyone go through that



如果您从零开始,这将是一个有效的选择。正如另一位发帖人所说,WCF 确实通过消除使用 System.Messaging 的必要性,让您远离一些 msmq-voodoo。但是,您已经编写了代码,所以我看不到公开 netMsmqBinding 的好处。端点。

If I went with a service I think I could employ a private queue instead of a public one



据我从您的描述中了解到,没有什么可以阻止您在当前场景中使用私有(private)队列。事实上,我建议始终使用私有(private)队列,因为它们更简单。

If I do put in the service, how much management would I need to have in place?



使用 wcf 服务将有更多的管理开销。因为您使用 WCF 堆栈包装发送-接收的每一端,所以有更多代码需要启动,因此可能会失败。众所周知,如果不启用完整的服务日志记录,WCF 堆栈异常就很难进行故障排除。

编辑 - 回应评论

I think for a private queue you have to actually be writing FROM the machine the queue sits on, which would not work in a networked environment



不真实。 MSMQ 支持对任何专用队列的事务性读取和写入,无论该队列是本地的还是远程的。

这是因为 任意 在 msmq 中将消息从一台机器发送到另一台机器时,无论队列地址如何,都会发生以下情况:
  • 发送机器上的队列管理器将消息写入临时本地“出站”队列。
  • 发送机器上的队列管理器联系接收机器上的队列管理器并传输消息。
  • 接收机器上的队列管理器将消息放入目标队列。

  • 如果您使用交易,上述步骤将包括 3 个不同的交易。

    需要记住的一点:在不同机器上的队列之间交换消息的最安全范例是远程发送,本地读取。

    所以这意味着当您发送消息时,您是在指示 msmq 发送到远程队列地址。但是,当有人向您发送东西时,他们也必须这样做。所以你最终只能从本地队列中读取,并且只发送到远程队列。

    通过这种方式,您可以获得最可靠的消息传递设置,因为在读取时,本地队列将始终可用。

    尝试一下!近 10 年来,我一直在使用 msmq 进行跨机通信,但从未使用过公共(public)队列。我什至不知道他们是为了什么!

    关于multithreading - 在具有多个用户的网络上使用 MSMQ 与在本地使用一个用户,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27930489/

    相关文章:

    c++ - WINAPI - 我想在一个单独的线程中进行消息泵

    java - 用于访问服务器的单个可运行程序,由不同类型的请求子类: how to ensure uniqueness?

    web.config 中的 WCF 服务 dataContractSerializer maxItemsInObjectGraph

    c# - 了解 WCF IsOneWay、CalbackContracts 和 Duplex - 我的假设是否正确?

    architecture - 您现在正在做MDA(模型驱动的体系结构)吗?如果是这样,您将使用哪些工具,其工作方式如何?

    带有 spring 注释方法的 Java .parallelStream()

    java - SWT 使用线程填充 GUI 小部件的正确方法?

    C# 异步调用垃圾回收

    javascript - Node 代理服务器,瓶颈?

    c - 文件什么时候真正写入磁盘?