【问题标题】:Use MSMQ queue to decouple message producer and consumer?使用MSMQ队列解耦消息生产者和消费者?
【发布时间】:2014-01-07 07:48:03
【问题描述】:

我将不胜感激有关 Windows 服务 (c#) 的一些设计建议,用于将报告发布到 SOAP 服务。

它从数据库中获取一组有限的报告(Oracle AQ 表中的报告),将它们聚合成一条消息,然后将此消息转发给 WCF SOAP 服务。 如果报告已通过 SOAP 成功传输,则将报告标记为“已发送”。 否则,它们会再次添加到 AQ 表中(通过 db 作业)。

所以我想出了以下设计。 最好的方法是什么? 队列会在可扩展性、健壮性、解耦方面改进设计吗? 在这种情况下使用排队是个好主意吗?

建议的设计 A: 具有 1 到 N 个线程的服务。 每个线程同步处理报告(获取报告、聚合、翻译、通过 SOAP 发送)

建议的设计 B: Windows 服务:

  • 1个MSMQ消息队列
  • 1 到 N 个生产者线程:(获取报告, 通过 MSMQ 聚合、排队消息)
  • 1 到 N 个消费者线程: (通过 SOAP 出队、翻译、分配)

提议的设计 C:

  • 具有生产者线程的 Windows 服务(通过 WCF NetMsmqBinding 客户端获取报告、聚合、将消息排队到私有 MSMQ 队列)
  • IIS/WAS 托管启用了 MSMQ 的服务(侦听 MSMQ 队列、出队、翻译、通过 SOAP 分配)

【问题讨论】:

    标签: c# multithreading wcf queue msmq


    【解决方案1】:

    您选择 MSMQ 有什么特别的原因吗?如果你使用你提议的设计 B,你可以使用BlockingCollection

    我认为 MSMQ 在这种情况下不会提供特别的优势,除非您需要多个进程或者您希望将其分散到多台计算机上。

    但是你真的需要多个线程吗?您的限制因素似乎是数据库访问时间或与 WCF 服务的通信。除非 WCF 服务必须进行一些主要处理才能调用作业成功。

    所以你确定你不能只拥有:

    while there are unsent jobs in the database
        get job
        send job to WCF
        if job sent successfully
            mark job as sent
    end while
    

    显然,我对您的情况的了解仅限于您在问题中发布的内容,因此我可能错过了一些重要的事情。

    【讨论】:

    • 我想过解耦消息创建和分发。因此,我尝试应用队列。但正如您所描述的那样,简单的设计(获取工作、发送工作、标记工作)就足够了。这也是我的第一个方法。排队是在 Oracle AQ 表中完成的。所以另一个 MSMQ 队列不会提供任何优势。远程 WCF 服务并不复杂(只有验证和持久性)。所以服务应该获取和发送作业。它基本上是一个消息代理。外部 WCF SOAP 服务接口可能会更改。它应该易于更换(对于其他客户)。
    • 目前我尝试设计服务(数据访问、消息聚合、WCF客户端调用)。具有 GetJob()/SetJobStatus 方法的 IIS/WAS/自托管 WCF 服务 (net.pipe) 是否会提供更好的分离以及更好的可重用性/可扩展性? Windows 服务本身只会调用 GetJob,将消息转发到外部 WCF 客户端,然后使用 SetJobStatus。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多