4

I have this scenario, guys-

A typical large-scale CMS application in which the following business transactions appear:

  • Users publish content immediately.
  • Users schedule content to be published.
  • Automatic process runs ,say, in 10 minutes interval, collects scheduled and ready (simply a status of the BO)content and sends it to publishing.

This is oversimplified description of the actual system. By saying publishing I mean a complex process consisting of 4 main sub-systems: building invocation arguments, generating html content by running another web app(asp.net), committing the transactional parties, and signaling the users about the publishing results. So the system looses ability to run the whole process in a single Mega-transaction, i.e. it's possible but not practical from the scalability/performance points of view.

There are several options for the sub-systems to communicate each other, like making use of MSMQ, SQL Service Broker, NServiceBus, and a chain of plain WCF one-way invocations (which is currently implemented). So, guys, I'm looking for some possibly more reliable and scalable solution for this processing because looks like the system will be getting more busy with growing number of users and , therefore, more content to be generated. Especially, once, mobile versions' support is requested by the clients.

One of my considerations is to queue all the users immediate requests using MSMQ where a dedicated WCF service will dispatch them next to the content generation module (web app). And so will do the windows scheduled task. I can't see how these messaging platforms could be useful but not residing them before the html generation. This really confuses me.

Can't figure out what technology will fit best for this on my own.Any help, considerations, sharing your experience will help me, guys.

Arman
  • 5,136
  • 3
  • 34
  • 36
  • It's difficult to know exactly what challenge you are facing. What is the issue you are struggling with and why does the solution involve queuing? – tom redfern Nov 23 '12 at 19:22
  • Well,nice question :) The current solution doesn't involve queuing, it's just a chain of several direct one-way calls in this form:both web app and win scheduled task call a WCF service which requests another web app that generates the output html and, in turn, forwards the processing to one more WCF that runs a heavy committing logic, updates the database and notifies(SignalR) the originally issuing clients about the result. Now, the real point is in the scheduled job which can concurrently issue a few hundreds of simultaneous requests. – Arman Nov 23 '12 at 20:12
  • This, + concurrent web user immediate requests can overload the html generation application, so having no real experience in ESB platforms and enough time before our first demos, I thought to add an MSMQ which could work as a somewhat reliable balancer before forwarding the bunch of requests down the execution path to the content generation. I know that's not the best solution, of course. – Arman Nov 23 '12 at 20:15

3 Answers3

3

You could use the saga capabilities in NServiceBus to model the process of publishing, including the scheduling part, as it has the ability to perform actions reliably after a certain delay with practically no overhead.

If you're happy enough to queue users immediate requests, then you could easily use NServiceBus as your API instead of cobbling something together yourself with MSMQ, WCF, and Windows Scheduled Tasks.

Udi Dahan
  • 11,932
  • 1
  • 27
  • 35
  • Looks good, then, what if users re-schedule their content. Does NServiceBus expose an API to query for a certain item and modify it. This is what precludes me from using MSMQ (scanning the queue isn't the case here). – Arman Nov 23 '12 at 15:14
  • Btw, Udi, the idea behind putting immediate requests in the queue too was in having just a single dispatcher instead of delegating the content generation proc from the users' app, since the scheduler queues itself. Still, interesting to see you reply on re-scheduling issue. I'm learning the NServiceBus, in meanwhile (can't get to the re-scheduling issue yet). – Arman Nov 23 '12 at 17:54
3

If all the players are SQL Server instances (or backed by such) then Service Broker has a big advantage. As is integrated in the SQL Engine it means that all those times when you have to engage in a local distributed transaction between the database and the message store (ie. every time you enqueue or dequeue a message) become a ordinary simple transaction since the database is the message store. This also gives advantages when you consider backup/restore since you can have a coherent backup for both the data and the messages (the database backup contains a backup of all the messages), you only needs only one solution for high availability/disaster recoverability: the database solution (clustering, mirroring) is also the messaging HA/DR story since the database is the message store. And built in activation eliminates the need to configure (and more importantly, monitor and failover in HA/DR failover cases) the external activation mechanisms. Not to mention that built-in activation has no latency while it can also adapt to spikes, something external scheduled activation can have problems achieving (external tasks must pool and have to balance the frequency of pooling with desired latency and consider spikes)

Remus Rusanu
  • 288,378
  • 40
  • 442
  • 569
  • +1, Remus. Thanks for such a detailed reply, I'm studying the service broker's features. Just the same question: is it possible to pick a message from the Service Broker and modify it, unlike MSMQ? It's a critical requirement for the system. – Arman Nov 25 '12 at 21:10
  • 1
    Have a look at http://msdn.microsoft.com/en-us/magazine/cc163586.aspx, I think is very similar to your requirements. – Remus Rusanu Nov 25 '12 at 22:14
  • 1
    BTW, about immediate vs. delayed action: always use message queues for events, never for storage. If you want to delay the processing the message you need to extract the data, save it as ordinary state (data in tables) and, with a system like SSB, [initiate a timer](http://msdn.microsoft.com/en-us/library/ms187804.aspx) and let the timer activate again the processing when more 'convenient'. – Remus Rusanu Nov 26 '12 at 14:51
  • so you suggest to store the bulk output args of the scheduled process (may contain a few hundreds at a time, in ten minutes interval) into the DB, and then extract/run them in smaller chunks, right, since there's no bulk queuing abilities, I guess? (instead of queuing them asynchronously for a further reliable/balanced processing)? – Arman Nov 27 '12 at 09:52
3

You will definitely require some business process handling.

Your immediate requests would translate to command messages. Once a command has been processed you could publish event messages that the next step in your process could pick up to continue the process. So you may not even need scheduling.

I have done something similar:

e-mail -> content engine -> document conversion -> workflow engine -> indexing -> workflow engine

No scheduling was involved. To get something done you send a command and when the command processing completes the endpoint publishes and event and whichever endpoint is subscribed to that event will receive a copy and know how to continue. I had a simple table structure keeping track of the data for the process along with the appropriate status.

For some parts of your system you may require more immediate processing. When you come across this you can install your endpoint service more than once and have one act as a 'priority' endpoint. As an example. In our document converter endpoint we would have to convert each e-mail body. Since we received thousands per day they would queue up quite a bit. This was done in the background with no real care for when it occurred. The users of the indexing web application, on the other hand, would need to convert certain documents immediately from the web-site. Sending to the same convert endpoint resulted in ad-hoc conversions waiting behind thousands of other conversion requests at times. So the response was not on. The solution was to simply install another converter instance (same binaries) and configure separate queues for the endpoint and then have all conversion request messages from the web servers route to the ad-hoc endpoint. Problem solved :)

As a side note: even when you do go with a web-service interface or WCF it may be a good idea to place that behind a service bus endpoint since the endpoint buys you quite a bit (retries / poison queues / etc.)

Since you seem to be in an evaluation stage you may want to take a look at my FOSS service bus: http://shuttle.codeplex.com/

This is what we used on the described system. There is a separate scheduler component should it be necessary (though we didn't use it on the project).

Eben Roux
  • 12,983
  • 2
  • 27
  • 48
  • Thanks, Eben, for sharing your experience. I was always wondering of having a service bus as a coordinator of the business workflow. When I got the system it was completely based on Win Scheduled executables running on a single machine with no monitoring abilities, not even to say about reliability. So we had to design a web-based monitoring tool for those background processes (maybe will drop it to codeplex someday). – Arman Nov 27 '12 at 09:00
  • For the shuttle would be very useful to schedule commands too and have a repository of them in case of re-arrangement is needed. Do you think it's possible with the shuttle? – Arman Nov 27 '12 at 09:03
  • @Arman: I don't quite understand what you mean but what we had was a little management shell where one could locate the relevant process data and then send relevant commands where necessary. So the support staff use this when anything goes wonky --- non-transaction systems can do this :) --- As far as the scheduling goes it is a generic command that is sent to an endpoint. We can take this offline if you wish (me at ebenroux dot co dot za) – Eben Roux Nov 27 '12 at 10:26
  • OK, I got the idea of the shuttle. I was looking for a built-in scheduling support for messages (commands), like the TimerManager in NServiceBus. – Arman Nov 27 '12 at 13:08