Team LiB
Previous Section Next Section

Golden Rules for Web Services

To design successful Web Services applications, you need to follow the "golden rules" presented here. To explain these rules, we'll use a scenario of a Web Service making calls to another Web Service. We have the client connecting to Web Service (Pink), connecting to Web Service (Blue).

The golden rules are as follows:

We'll take a closer look at each of these rules in the following sections.

Golden Rule 1: Understanding Settings

The following is the threading model for a Web Service making calls to another Web Service:

  • Thread 1[IO/Worker]: Request is made to the Pink tier .asmx, which in turn calls the Web Service on the Blue tier.

  • Thread 1[IO/Worker]: Sends a POST request and blocks on ws2_32!Send.

    Note 

    With IIS 5, Thread 1 would most likely be an IO thread. With IIS 6, Thread 1 would be a worker thread.

  • Thread 2[IO]: Receives HTTP 100 Continue via WSARecv.

  • Thread 3[Worker]: Sends SOAP envelope via WSASend.

  • Thread 2[IO]: Receives the result of Web Services via WSARecv.

  • Thread 1[IO/Worker]: Returns from ws2_32!Send.

    Note 

    If security was used to call the Web Service on the Blue tier, there is the potential to use a fourth thread.

Table 18-1 describes the Web Services settings and shows some simple formulas for determining the proper settings.

Table 18-1: Web Services Settings

Setting

Description

Proper Setting

maxConnections

Sets the maximum concurrent outbound Web Service calls per IP address.

Set to the number of simultaneous outbound connections to a specific IP address that you expect. Should be incremented in steps of 4 to determine optimum settings for application and hardware.

minFreeThreads

Preserves a set number of threads for outbound Web Service calls. In the example presented here, we use three threads for each Web Service call, and possibly one more if security is involved.

maxConnections times 3 (use 4 if security is being used).

minLocalFreeThreads

Same as minFreeThreads, but focuses on requests that are outbound to the same server.

 

maxIOThreads

Determines the total number of IO threads available in the thread pool that can service requests.

Needs to be greater than maxConnections + minFreeThreads.

maxWorkerThreads

Determines the total number of worker threads available in the thread pool that can service requests.

Needs to be greater than maxConnections + minFreeThreads.

Note 

When the number of threads running in the thread pool exceed the value of minFreeThreads, you will begin to queue inbound requests.

To tune the thread pool performance, if your CPU utilization is low and you are queuing requests, you should increase the value of maxIOThreads and maxWorkerThreads . On the other hand, if you CPU utilization is high, you should lower these settings.

Note 

When CPU utilization exceeds 95 percent, you do not create additional threads. When CPU utilization is below 80 percent, you free unused threads.

Golden Rule 2: Understanding Timeout Settings

The connection timeout setting for a Web Service proxy should always be less than the settings defined by HttpRuntime.executionTimeout . If you do not follow this pattern, you will leak socket connections.

You must also be aware of how time is spent in your methods. For example, if you have configured your executionTimeout on the Pink tier to 90 seconds and have also configured the Web Service proxy to 70 seconds, you can run into problems. Let's say the incoming request to the Pink tier consumes 50 seconds before it makes the call to the Blue tier. This would allow you approximately 20 seconds to run the Web Service call to the Blue tier.

The recommendation is to make sure that the executionTimeout setting is no less than the time it takes to get to your Web method call plus the proxy timeout. So in our example, if testing proved these numbers to be consistent, our executionTimeout should be no less than the value defined in testing to be the amount of time it takes to get to the Web Service call, plus the maximum amount of time it takes to execute the call.

To recap, given a call to a Web method on the Pink tier, determine the appropriate timeout setting as follows:

  1. Define the time it takes from the beginning of the Web method in the Pink tier to the call to the Web method on the Blue tier. Let's call this A.

  2. Define the maximum amount of time we are going to set for the Web Service proxy (Blue). Let's call this B.

  3. Set the value of executionTimeout as greater than the value of A + B.

Golden Rule 3: If a Timeout Occurs in One Tier, Abort Outbound Web Service Calls to the Other Tier

Use GetWebRequest to get the current request, as follows:

Private WebRequest -request;
Protected override WebRequest GetWebRequest(Uri uri)
{
            _request = base.GetWebRequest(uri);
            return _request;
}

Then do the following in the method that invokes the Web Service:

Public string SleepItOff(int sleepTime)
{
            Bool timeout = true;
            Try
            {
                       Object[] results =
                         this.invoke("SleepItOff", new object[]{sleepTime});
                       Timeout = false;
                       Return ((string)(result[0]));
            }
            Finally
            {
                       If(timeout && _request!=null)
                       _request.Abort();
            }
}
Note 

You must place the abort code in the finally block, because when executionTimeout is reached, you call ThreadAbortException, which can be caught in a catch block.

Golden Rule 4: Do Not Write a Web Service Method That Works in a Tight Loop

The design in version 1.0 of the framework was that inbound requests were handled by I/O threads. By design, the IO completion port will allow only the number of threads executing to be equal to the concurrency value. If you have a Web method that enters a tight loop or takes a sufficiently long period of time to execute without entering a wait state, the scalability of your Web Service will be impacted.

If you need to use a Web method that works in a tight loop, you should queue the work to a worker thread, via the following call:

ThreadPool .QueueUserWorkItem(new WaitCallback (DoBackgroundWorkLong));

This will place the IO thread in a proper sleep, allowing for other IO threads to get execution time.

Golden Rule 5: Do Not Call STA Objects from Web Services

Accessing STA objects from a Web Service is not supported for the simple reason that STA objects provide automatic synchronization to all clients. There are some workarounds that can be found in the Microsoft Knowledge Base article "XML Web Services and Apartment Objects," which you can find at http://support.microsoft.com/?id=303375.


Team LiB
Previous Section Next Section