Maintaining High Availability

Third-Party Web Services and Availability

Web services enable you to leverage functionality exposed by third-party Web services via the Internet. However, the overall availability of your application will be affected by the availability of the third-party Web services. In this section, I offer some techniques you can use to help ensure that a third-party Web service does not adversely affect your application's uptime.

One option is to eliminate dependence on a third-party Web service altogether by reproducing its functionality in house. However, you should weigh the potential benefits of increased control against the time and cost this approach will require. For example, the Microsoft TerraServer .NET Web service provides access to terabytes of satellite images. Reproducing this functionality would be very expensive and time intensive.

In addition, the third-party Web service might actually provide higher availability than the client application that uses it. High availability requires a discipline that few IT organizations have mastered. In other words, I anticipate a strong market for reliable third-party Web services that meet a business need.

If you have decided to leverage a third-party Web service, consider establishing a service-level agreement (SLA) with the provider. An SLA is a contract between you and the Web service provider that defines the service level you expect (uptime, response time, and so forth). If the service level is not met, penalties are often imposed on the Web service provider. Penalties can range from waiving the fees for accessing the Web service based on the amount of time the Web service is down to compensation based on the financial impact on your business.

Even if you choose a reliable provider and draft a strong SLA, outages can still occur. You might consider implementing a strategy so that if the third-party Web service becomes unavailable, the outage will not adversely affect your clients. In the next sections, I examine two such strategies: failing over to an alternative Web service and implementing an offline mode.

Failing Over to an Alternative Web Service

When practical, you can consider forwarding failed requests to an alternative Web service. For example, say that Woodgrove Bank also hosts a Stock Quote Web service that you use within your application. If the Web service goes down and is no longer returning stock quotes, you can obtain the stock price from another Web service rather than return an error to the client. The following code shows a relatively simple failover technique:

using System; using System.Threading; public class StockQuoteProxy {     bool useBackup = false;     WoodgroveProxy primary = new WoodgroveProxy();     ProsewareProxy backup = new ProsewareProxy();

I declare two proxy objects for accessing the Stock Quote Web service, one exposed by Woodgrove Bank and one exposed by Proseware Bank. I also declare a Boolean field to indicate whether the proxy should fail over and use the backup proxy object.

    public double GetQuote(string symbol)     {         if(! useBackup)         {             try             {                 // Obtain quote from primary proxy.                 return primary.GetQuote(symbol);             }

Next I define the GetQuote method. By default, it will attempt to obtain a quote for the specified stock symbol via the primary proxy object.

            catch(Exception e)             {                 // Fail over to the backup proxy.                 useBackup = true;                 // Configure object to revert to the primary proxy                 // in 15 minutes.                 Thread thread = new Thread(new ThreadStart(this.Reset));                 thread.Start();                 // Obtain quote from backup proxy.                 return backup.GetQuote(symbol);             }         }

If the primary proxy object throws an exception, I set the useBackup property to true so that the instance of StockQuoteProxy will fail over to the backup proxy object. A new thread will also be spawned, with the responsibility of reverting to the primary proxy object in 15 minutes. Finally the backup proxy will be used to try to obtain the quote.

        else         {             // Obtain quote from backup proxy.             return backup.GetQuote(symbol);         }     }

If the GetQuote method is called when useBackup is set to false, the backup proxy is immediately called.

    private void Reset()     {         Thread.Sleep(15000);         useBackup = false;     } }

Finally I implement the Reset method. This method is invoked within its own thread, where it waits for 15 minutes and then sets the useBackup field back to false. The next time the GetQuote method on the instance of the StockQuoteProxy class is called, the object will attempt to obtain the quote from the primary proxy.

Another alternative is to leverage UDDI. If the Web service supports a standard interface that is published in UDDI, you can query the UDDI directory to locate alternatives if your primary Web service becomes unavailable. The following code demonstrates this technique:

using System; using System.Threading; using Microsoft.Uddi; using Microsoft.Uddi.Binding; public class StockQuoteProxy2 {     primaryUrl = "http://www.woodgrove.com/StockQuote.asmx";     string [] backupUrls;     int backupUrlIndex = 0;     WoodgroveProxy proxy = new WoodgroveProxy();     public StockQuoteProxy2()     {         Inquire.Url = "http://uddi.microsoft.com";         // Find all bindingTemplate entities that expose         // the StockQuote interface.         FindBinding findBinding = new FindBinding();         findBinding.TModelKeys.Add("uuid:272208dd-4f22-4df1-83a6-b8fcff936523");         BindingDetail bindingDetail = findBinding.Send();         // Populate the array of backup URLs.         int count = bindingDetail.BindingTemplates.Count;         proxyUrls = new int[count];         for(int i = 1; i < count; i++)         {             proxyUrls[i] = bindingTemplate.AccessPoint.Text;         }     }     public double GetQuote(string symbol)     {         if(! useBackup)         {             try             {                 // Obtain quote from primary proxy.                 proxy.Url = primaryUrl;                 return proxy.GetQuote(symbol);             }             catch(Exception e)             {                 // Fail over to the backup proxy.                 useBackup = true;                 // Configure object to revert to the primary proxy                 // in 15 minutes.                 Thread thread = new Thread(new ThreadStart(this.Reset));                 thread.Start();                 // Obtain quote from backup proxy.                 return this.GetQuote(symbol);             }         }

If the primary proxy object throws an exception, the useBackup property is set to true so that the instance of StockQuoteProxy will fail over to the backup proxy object. A new thread will also be spawned, with the responsibility to revert back to the primary proxy object in 15 minutes. Finally the backup proxy is used to try to obtain the quote.

        else         {             // Obtain quote from backup proxy.             proxy.Url = backupUrls[backupUrlIndex];             try             {                 return this.GetQuote(symbol);             }             catch(Exception e)             {                 // If there is another backup proxy, call it.                 // Otherwise, rethrow the exception.                 if(backupUrls.NextUrl)                 {                 lock(backupUrls)                 {                     if(backupUrls.Position < (backupUrls.Count - 1))                     {                         backupUrls                 backupUrlIndex ++;                 if(backupUrlIndex < (backupUrls.Count-1))                 {                     throw;                 }                 return this.GetQuote(symbol);             }         }     }

If the GetQuote method is called when useBackup is set to false, the backup proxy will immediately be called.

    private void Reset()     {         Thread.Sleep(15000);         useBackup = false;     } }

Finally I implement the Reset method. As in the previous example, the Reset method causes the instance of the StockQuote2Proxy class to retry the primary proxy after 15 minutes. Notice that the Reset method does not reset the index for the backup proxy. If the primary proxy fails again, the current backup proxy will once again be called.

Creating an Offline Mode of Operation

In some cases, using an alternative Web service is not practical. For example, I cannot use another bank's Web service to modify the banking services I set up with Woodgrove Bank. In these situations, you should determine whether you can provide an offline mode for interacting with the Web service.

When you consider your offline strategy, take a hard look at the synchronous interactions with the Web service and determine whether they can be performed asynchronously. For example, the client application for the Banking Web service might allow users to request fund transfers. If the request is not honored within a specified period of time, the client can be notified.

When the client issues a request to transfer funds, the request will be queued on the client. If the Banking Web service is on line, the request will immediately be taken off the queue and processed. If the Web service is off line, the request will stay queued until the Web service comes on line or the request has expired. If the request expires, the client will be notified.

Let's say the Banking Web service also allows users to modify their account information, such as their mailing address. And suppose that the application used to modify the information presents the customer with a form prepopulated with the current information. The customer can make the necessary modifications and then submit the updated information.

The client application must first obtain the current state of the customer's account information to display it to the user. If the Web service is unavailable, there is no way to obtain that information.

But obtaining the most current information from a Web service is often not absolutely necessary. For example, the customer's account information is relatively static. When the Web service is on line, the client application can cache the state of the user's account information. If the Web service becomes unavailable, the client application can display the cached data to the user.

After the customer has modified the account information, the client application can submit the updated information back to the Banking Web service via the queuing method I described earlier.



Building XML Web Services for the Microsoft  .NET Platform
Building XML Web Services for the Microsoft .NET Platform
ISBN: 0735614067
EAN: 2147483647
Year: 2002
Pages: 94
Authors: Scott Short

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net