简体   繁体   中英

Decoupling MSMQ By Sending Messages Through a WCF service

I have several .Net applications (not yet built) that need to send error messages, warnings, alerts, heartbeats, etc. to a database so they can be viewed in an alarm summary dashboard. This can't slow the apps down too much. It has to be fast. I want a way to prioritize certain messages so they are displayed right away in the dashboard.

I am thinking that MSMQ is the way to go because there might be a ton of messages coming in and you can make several queues.

Would it be faster to make my apps send the messages directly to MSMQ? Or, would it be faster to send them to a WCF service with NetMSMQBinding?

If I send the messages directly to MSMQ then the apps are tightly coupled to MSMQ and if I want to scrap MSMQ later and use something else I will be screwed. I don't want to have to make changes to the apps once they are in the wild every time the alarm summary app changes.

If I send the messages to a WCF service with the NetMSMQBinding then I still tightly-couple my apps to MSMQ, right?

This alarm summary application could be huge, effecting every app in the entire system and it has to be done correctly.

If you wish to avoid tight coupling to MSMQ, I'd suggest using something like a homegrown bus abstraction that takes in the message and then sends it to MSMQ in whichever way you'd like to do so. That way, you could always plug a different implementation that uses whatever you wish (RabbitMQ, some direct db persistence or whatever you may think of). Otherwise, personally I'd try and keep the message handling as less costly and as short as possible. You might also want to have a look at articles on msmq performance such the this one .

I'm just finishing a huge project for the company where I work that is similar to yours.

It relies purely on WCF using NetTcpBinding and persisting all the information on a Sql Server database.

The main WCF service is the responsible for persisting the information to the database. Others wcf services return the data to the clients that need it (a 32" touchscreen hanging in our wall, desktop gadgets, smartphones).

There's a common library that contains the contract definitions and all the client related stuff that is used by all the apllications here (10+). All this applications log everything against the wcf service (always in async operations): exceptions, warnings, heartbeats, even debug information. The quantity of clients here is not huge, it's about 60 pc's running 1 or 2 apps at the same time.

The dashboard is a WPF application that keep contacting a wcf service to know if there are updates based on the priority and then display them in a nice UI.

Between the 60+ clients we have 15 RTU that send temperature (ºC) and pressure (bars) of natural gas pipes from 3 different cities to the same server, this information is received by a windows service via Tcp and then send to the wcf service (on the same server). All this data is critical!! We even have another windows service that keeps querying a wcf service to find important events and send SMS to the persons related to that type of event.

Soooooo, IMO wcf is a great technology for achieving your goals!

It is not possible to insulate yourself entirely from the consequences of a technology choice, and at some point attempting to do so you will get diminishing returns.

I know we are all taught to avoid coupling at all costs, like it's some kind of disease, but one of the benefits of using WCF in the first place is that you are not hard coupled to a specific transport. You can swap out MSMQ to TCP with configuration changes only.

As @nieve suggests, by creating an abstraction you are indeed decoupling yourself from implementation details, in this case WCF. However, is coupling yourself to your abstract bus representation any better? You may get less "coupling" but arguably at the expense of greater obfuscation .

A call to MSMQ over WCF has the benefit that it's a small amount of code and can be easily picked up by other developers with almost zero analysis overhead. I would suggest timidly that you are perhaps over-engineering a solution to a problem which does not really exist.

Think about developers who are coming new onto your project in say 12 months time. You want to build a system where they don't spend the first two months learning it before they can be productive. Using familiar frameworks which have been designed to decouple you to some degree may go some way to achieving this.

In my tests WCF and NetTcpBinding is quite fast (< 1ms roundtrip time).
By using async, you avoid locking an application, when some connections fail.
AsyncWcfLib could help rising the level of abstraction.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM