Build Scalable Web Services With Msmq

Imagine you've been asked to build a help-desk-request logging system for a large IT ... VB.NET, SQL Server. 2000, ASP.NET. Other: Windows XP. Professional ... code for a sample application that allows you to input request items manually, ...
125KB taille 16 téléchargements 217 vues
Build Scalable Web Services With MSMQ

Learn how to overcome a common scalability limitation of Web Services.

by Josh Lane

Many of the first Web Services you create are likely to be synchronous, where processing for each service invocation is handled at the time of the invocation. However, Web Services of this sort can have scalability limitations. You can overcome these issues by using Microsoft Message Queue (MSMQ) with Web Services. In this column, I'll give an example of an asynchronous processing system that performs help-desk-request logging.

Technology Toolbox VB.NET, SQL Server 2000, ASP.NET Other: Windows XP Professional

Imagine you've been asked to build a help-desk-request logging system for a large IT department. The system should accept requests programmatically; that is, a help-desk request has a known format and can originate from many sources, only one of which might be an intranet site. This would enable malfunctioning network printers to submit requests on their own behalf, for instance. You decide to implement the functionality as a Web Service. However, the company already has an existing request logging system. It's slow, barely functional, and decidedly grumpy in its old age, but the new software needs to interact with this old system. Complicating matters further, it needs to write requests redundantly to a new request database too. Your initial coding attempt might seem like a viable solution to the task of logging help requests into both databases (see Listing 1). But consider the nature of the work being done. You must establish connections to both databases at some point during request processing. One or both database machines could go down. Or too many simultaneous database connections might exist already. Either database machine might be used for other concurrent operations, slowing down response times for your request logging software. And remember, your team identified a potential performance problem already with the older system. This can affect your requestlogging Web Service in many ways, notably as a deterrent to system scalability. Scalability is a measure of your Web Service's ability to handle a potentially ever-increasing number of requests with minimal or no change to the software's logical architecture. If you apply this definition to the help-request Web Service, you see that the scalability problem lies in the service's synchronous nature: Requests are submitted and processed, and the results are returned to the user, all as a single operation. Each request represents a time-consuming task that ties up resources on the Web server for each request's potentially long life. Increasing the number of simultaneous requests only worsens the resource situation on the Web server. Change to an Asynchronous Model You can solve this problem by changing the Web Service from a synchronous request model to an asynchronous request model. The idea is simple: If you can introduce an intermediate component into the request-logging architecture that can take requests rapidly and guarantee their eventual delivery to both logging databases, you're in a much better position to scale your system gracefully over time. This new system is asynchronous because the client doesn't wait for a response indicating success or failure of the entire logging operation. Instead, users wait for a response indicating they initiated a logging request successfully, and they rely on guarantees provided by the system itself that their request will eventually be logged properly. A useful analogy is to consider how the postal system works. If the postman pulled up to your mailbox, took your outbound mail, and then delivered each piece of mail one by one to its destination, it might take him days to deliver only your mail for just one day! This isn't an efficient use of the postal system's limited resources; scalability (the post office's ability to handle an increasing volume of mail without major changes to its internal structure) is severely hampered. Instead, the postman takes your mail and puts it in a big pile with the other outgoing mail. At some point in the future, all the outgoing mail is processed; there's an implicit guarantee

1

your mail will be delivered eventually to its proper destination. As a client of the postal system, that's all you care about. This allows the system to be much more efficient and to scale gracefully over time. Your goal in building the request logging system is the same. You can build such an asynchronous processing system using MSMQ. MSMQ is a middleware subsystem that comes pre-installed on all Windows 2000 and Windows XP computers. It provides a means of storing messages of arbitrary content for forwarding or retrieval in operating-system-level structures called queues. MSMQ queues are Distributed Transaction Coordinator (DTC)-aware resource managers, meaning that send and receive operations against a queue can operate within a COM+ transaction. This also allows queues to provide client delivery guarantees necessary for building scalable Web Services. The MSMQ subsystem can provide additional optional services such as Windows-based queue security and automated forwarding of messages to other queues. In addition, you can access the full complement of MSMQ services from the System.Messaging API in .NET (see Resources for more details about MSMQ). You need to divide the task of logging the requests into three parts when using MSMQ to build a scalable, robust, help-request logging system. The first task is sending the request from the client, the second is receiving the request and moving it into the request queue, and the third is removing the request from the queue and writing it into both request databases. In this way, the queue sits "in between" the second and third parts of the system. The Web Service HTTP gateway receives requests and adds them to the queue immediately. Meanwhile, another separate component handles requests as they appear in the queue. In this way, the processing time and resources needed to take requests aren't tied directly to the processing time and resources needed to process requests. Build the Components First, you need to build a component that's triggered when the request message queue on the server receives a help request. This component removes the message from the queue and invokes the data components that in turn write the request to each request database. You perform all this work within the scope of a single COM+ transaction (see Listing 2).

2

You also need to build the data components themselves (referred to as OldSystemRequestWriter and NewSystemRequestWriter in the code). Also, don't forget to register the RequestHandler, OldRequestWriter, and NewRequestWriter components with the COM+ catalog using regsvcs.exe (see Figure 1). You can download step-by-step instructions, as well as complete code listings in both VB.NET and C#. Next, you need to set up the MSMQ queue that holds incoming help-desk requests. Also, you need to add an MSMQ Trigger to your queue. You use Triggers to invoke component methods or executables automatically as a result of messages arriving at the target queue. Rules can specify additional conditions for message processing—for example, based on message content. For the request processing system, you can use a trigger with a single rule that invokes the RequestHandler component's ProcessRequest() method (see Figure 2). The download includes detailed explanations of these steps.

3

Figure 2. Create an MSMQ Trigger Rule. Trigger rules allow your components to be invoked automatically as a result of messages arriving at the target queue. You can use MSMQ Triggers to process queue messages instead of implementing a traditional queue listener; be sure you understand the usage semantics of each option before choosing one.

After this, you need to build the Web Service that accepts incoming requests and submits them to the request queue (see Listing 3). Note that the Web Service uses a local MSMQ transaction to send the request; a COM+ transaction is overkill here because the operation involves only a single resource manager (the queue). Finally, you need to build the client code used to submit requests to the system. I've included code for a sample application that allows you to input request items manually, to demonstrate the functionality. The result of your efforts is that you have a help-desk-request logging system that's scalable, flexible, and robust. The Web Service is merely responsible for sending requests to an input queue; this allows you to maximize precious Web server resources and minimize client response times. The queue guarantees delivery of messages to the request processing logic, even if the server crashes. Also, you've decoupled request receiving from request processing, allowing greater ability to evolve the system over time as new functionality is added. Perhaps you can provide a separate system for clients to check the status of submitted requests. The possibilities are numerous. The concepts I've presented here are useful for many types of applications. In general, this model can work if clients submit asynchronous requests to your application. Many e-commerce, B2B middleware, and enterprise software architectures fit this description, so you can consider MSMQ and VB.NET solutions such as the one presented here for these scenarios.

4