|
Enterprises are beginning to develop and deploy applications with Web services, a standards-based approach to achieving application interoperability. Web services technology is enabled by a set of standards that specify description, discovery, and invocation via the Internet.
Web services has the potential to remove the long-standing barriers between
software applications, simplifying partner integration, cutting development time and costs, and extending the lifetimes of legacy systems.Unfortunately, the Web services model isn't without drawbacks; first and foremost are performance and scalability. Through close analysis, it's apparent that the technologies that underpin Web
services involve significant overhead. If these inefficiencies aren't addressed, the viability of the Web services paradigm could be threatened.
This article examines the bottlenecks inherent in existing Web services
technologies and explores optimization techniques that can be used to mitigate these bottlenecks.
Overview of Web Services
Before delving into the bottlenecks associated with the Web services framework, it's useful to examine the details of the underlying technologies. This article assumes that you are familiar with existing Web services-enabling technologies: Simple Object Access Protocol (SOAP), Web Services Description Language (WSDL), and Universal Description, Discovery, and Integration (UDDI).
SOAP is an extensible XML messaging protocol. It defines an XML encoding for function calls and their parameters, allowing applications to communicate with one another regardless of their environments. WSDL is an XML encoding for the description of Web services, specifying properties of services, such as what a service can do; how to invoke it; and where it resides. UDDI is a repository-based registry service for finding and publishing Web services.
Let's look at an example of Web services message exchange to see how these technologies work. Consider a portal application that serves stock quotes, weather, and news, each retrieved from its respective service provider. We'll use the stock quote example to examine the Web services interaction in greater detail. We'll assume that the portal has already identified the provider and has obtained the service description, i.e., WSDL. (These steps can be handled easily using the UDDI find and publish APIs.) Also, while SOAP is independent of transport protocol, we'll consider SOAP over HTTP in this article, since this is the most commonly used transport.
In the example shown in Listing 1 , the portal application is the Web service consumer, and the stock quote service is the provider. The consumer and provider applications must each perform several tasks to complete the stock quote Web services transaction. The consumer executes a program that prepares a SOAP request, sends it to the provider over HTTP, receives the SOAP response, extracts the response, and performs postprocessing to convert the response into a format appropriate for consumption. Listing 2 provides sample Java code for a consumer application that performs these tasks. This example is based on the Apache SOAP implementation.
To retrieve the quote for "IBM," invoke this program using the following command:
java getQuote http://localhost:8080/axis/servlet/operouter
The input arguments represent the method name, service URL, and parameters (symbol in this example), respectively. These values are obtained from the WSDL for the service. The program first processes these input arguments, which are used to build the call object. Next, the call.invoke method prepares the SOAP request, sends the request over HTTP, and receives the response.Finally, the response is checked for errors and any needed post-processing is done. Figure 1 illustrates these consumer-side tasks in detail.
The SOAP-specific steps that must occur on the consumer side typically include the following:
- A SOAP client object is created.
- The service method and parameters are obtained. These items may be read from the WSDL file, which may or may not exist locally.
- The parameters needed for the method call are serialized into a SOAP request (XML format).
- The SOAP request message is encoded into an HTTP request.
- The HTTP request is sent to the service provider.
- The HTTP response is received.
- The HTTP response is decoded into the SOAP response message.
- The SOAP response message is deserialized into the method response format.
Figure 2 shows the steps required on the provider side. The HTTP Request Handler forwards the request to the SOAP Dispatcher, which controls the SOAP processing for the request:
- The HTTP request is decoded into the SOAP request message.
- The SOAP request is deserialized, i.e., the parameters are converted to the appropriate types needed to invoke the service method.
- The service method is invoked with the appropriate parameters.
- The service method response object is serialized into a SOAP response message.
- The SOAP response message is encoded into an HTTP response.
- The HTTP response is sent back to the consumer.
Delays in Web Services Transactions
A number of steps are required to carry out a single Web services transaction. Each of these steps adds delays to the end-to-end service response time. The specific delays associated with Web services can be identified as follows:
Object instantiation: Object instantiation occurs on both the consumer and provider sides. The consumer, for instance, creates a SOAP client object. The provider usually creates application objects needed in executing the service method logic. Creation of such objects is costly in terms of processing and I/O operations. Furthermore, object creation increases the burden of memory management, i.e., garbage collection in Java environments, which can severely impact application performance.
Serialization/Deserialization: Serialization and deserialization occur on the consumer and provider sides. These tasks require parsing operations, adding delay.
Encoding/Decoding: Encoding and decoding occur on the consumer and provider sides. These steps require string processing operations, adding delay.
Service method invocation: Service method invocation occurs only on the provider side. In addition to object creation, this step often includes numerous other tasks, such as I/O calls to databases and data transformations. In addition, the multilayered application-design approach followed by most enterprises typically incurs cross-tier communication costs since the applications that create objects often involve several layers of nested callouts.
Network transmission: The exchange of SOAP messages between the participating applications occurs over a network. Regardless of whether these applications reside locally or remotely, each Web service exchange requires network communication. Thus, for each service invocation, communication between the two applications requires traversal of a network protocol stack (e.g., TCP/IP), which adds to the service response-time latency. This problem is exacerbated by the increased bandwidth requirements of SOAP, which is a text-based protocol.
It's important to note that each step must occur for each Web service request. Referring to our portal example, this means that for each request of the portal page, these steps must occur for each of the portal page elements (stock quotes, weather, and news). As the number of concurrent requests increases, these delays can cause serious performance and scalability problems.
Web Services Optimization Techniques
There are few solutions currently available to address Web services bottlenecks. One promising technique is to employ various types of caching in order to bypass many of the SOAP-related operations. I discuss three broad types of Web-services caching: consumer-side caching, provider-side caching, and gateway caching.
Consumer-Side Caching
Caching the results of Web services requests at the consumer side can reduce the end-to-end service response time. This type of caching has been suggested for Java applications as well as for .NET applications. There are different ways to implement such caching mechanisms. For instance, the cache itself can be an in-process or an out-of-process cache. An in-process cache is relatively easy to implement and is most appropriate for applications running on a single application server. An out-of-process cache allows for greater scalability and is most appropriate for applications running on multiple application server instances. However, out-of-process caches are more complex to implement and maintain.
It's useful to look at an implementation of consumer-side SOAP caching. As an example, I look at an implementation that utilizes the Cache Management design pattern for caching operations. This example is based on an implementation that utilizes the Business Delegate design pattern. For the sake of brevity, I consider only the caching portion of this implementation in this article. Listing 2 shows the cache methods for inserting into and retrieving items from a local cache.
We use the StockQuote service example to illustrate how consumer-side caching can be incorporated. Listing 3 shows an alternative version of the getQuote consumer code. This code checks the local cache for the object before invoking the SOAP call. If the object isn't found in cache, the SOAP call is executed and the returned SOAP response object is inserted into the cache. This example uses the symbol parameter as the cache key.
By caching SOAP response objects at the consumer side, the serialization, encoding, service invocation, and decoding steps shown in Figure 1 can be bypassed.
Provider-Side Caching
On the provider side, recall that the HTTP Request Handler channels SOAP requests to the SOAP Dispatcher (see Figure 2). Caching SOAP response objects can be implemented by modifying the HTTP Request Handler program. For instance, with a Java-based service, the HTTP Request Handler is a servlet that can be modified to invoke the cache.fetchObject method before sending the request to the SOAP Dispatcher, in much the same way as was done on the consumer side. When a SOAP response object is not found in cache, the usual chain of events happens (including service method execution), and the cache.addObject method is invoked to insert the response object into cache.
By caching SOAP response objects at the provider side, the deserialization, service-method execution, serialization, and encoding steps shown in Figure 2 can be bypassed. Conventional server-side caching techniques (e.g., application server caching and database caching) can also be employed at the provider side to reduce service-method execution delays.
Gateway Caching
With the rise of Web services, a new class of solutions has emerged - Web services gateways. Web services gateways serve as a centralized point through which all Web services traffic flows and provide a variety of functionality including security, monitoring, logging, and management. Although these gateways provide such value-added features, they also add delay since additional processing operations must be performed for each request. At a minimum, some type of inspection must be done for each SOAP request. In many cases, this may require decoding and deserializing the SOAP request, performing the required operations (e.g., authentication and transformations), serializing and encoding a new SOAP request, and finally, forwarding the request to its destination. As the number of requests increases, the gateway can quickly become a bottleneck.
To mitigate these delays, SOAP response objects can be cached at gateways. Some Web services-gateway vendors have incorporated some form of caching into their gateway products. However, most rely on in-process caching, which suffers from scalability limitations. Given this issue, expect to see out-of-process caching incorporated into Web services-gateway products in the near future.
Conclusion
Web services offer the potential to simplify partner integration, cut development time and costs, and extend the lifetimes of legacy systems. However, there are serious performance and scalability issues with the Web services paradigm. Before the benefits can be realized, enterprises must ensure that their infrastructures are ready to handle the inherent bottlenecks associated with Web services transactions.
Optimization techniques, such as SOAP caching, are emerging to address these bottlenecks. The three caching techniques discussed here can help reduce SOAP-related delays. The good news is that these techniques are quite complementary, since they each address different types of Web services bottlenecks. With some cooperation among consumers, providers, and intermediaries, further optimizations are possible. For instance, if the parties at the various endpoints are aware of optimization techniques employed by one another, it may be possible to eliminate certain redundant or unnecessary operations that could not be eliminated otherwise.
References
Azim, O., and Hamid, A.K. (2002). "Cache SOAP Service on the Client Side."
www.javaworld.com/javaworld/jw-03-20 02/
jw-0308-soap_p.html.JavaWorld.
Bequet, Henry. (2002). Professional Java SOAP. Wrox Press.
Grand, M. (1998). Patterns in Java. John Wiley and Sons.
"XML Web Service Caching Strategies."
http://msdn.microsoft.com/library/default.asp?url=
/library/en-us/dnservice/html/service04172002.asp
Sun Microsystems, Inc. J2EE Patterns Catalog.
http://developer.java.sun.com/developer/
restricted/patterns/BusinessDelegate.html
About The Author
Helen Thomas is the CTO and cofounder of Chutney Technologies, a software company
that develops solutions to improve the scalability and performance of enterprise
applications. She is also an Assistant Professor of Management Information
Systems at Carnegie Mellon University. Helen received her Ph.D from Georgia Tech,
an M.S.E. degree in Operations Research and Industrial Engineering from the
University of Texas, and a B.S. degree in Decision and Information Sciences from the
University of Maryland.
HELEN.THOMAS@CHUTNEYTECH.COM
Identifying and Eliminating Web Services Transaction, by Helen Thomas
WSJ Vol 02 Issue 09 - pg.14
Listing 1
public class getQuote {
public static void main (String[] args) throws Exception {
// Process the arguments.
int offset = 3 - args.length;
String encodingStyleURI = args.length == 3
? args[0].substring(1)
: Constants.NS_URI_SOAP_ENC;
URL url = new URL (args[1 - offset]);
String symbol = args[2 - offset];
// Build the call.
Call call = new Call ();
call.setTargetObjectURI ("urn:xmltoday-delayed-quotes");
call.setMethodName ("getQuote");
call.setEncodingStyleURI(encodingStyleURI);
Vector params = new Vector ();
params.addElement (new Parameter("symbol",
String.class, symbol, null));
call.setParams (params);
// Make the call.
Response resp = call.invoke (/* router URL */ url, /*
actionURI */ "" );
// Check the response.
if (resp.generatedFault ()) {
Fault fault = resp.getFault ();
System.out.println ("Ouch, the call failed: ");
} else {
Parameter result = resp.getReturnValue ();
System.out.println (result.getValue ());
}
}
}
Listing 2
public synchronized void addObject(Object key, Object value)
{
if (key != null && value != null)
{
cache.put(key, value);
}
}
public Object fetchObject(Object key)
{
if (key == null)
{
return null;
}
return cache.get(key);
}
Listing 3
public StockQuote getQuote(String symbol)
{
StockQuote stockQuote = null;
if(symbol != null)
{
stockQuote = (StockQuote) cache.fetchObject(symbol);
if(stockQuote == null)
{
synchronized(cache)
{
stockQuote = (StockQuote) cache.fetchObject(symbol);
if(stockQuote != null)
{
return(stockQuote);
}
Vector params = new Vector();
params.addElement(new Parameter("symbol",
String.class, symbol, null));
stockQuote = (StockQuote) soap.invoke("getQuote",
params);
if(stockQuote != null)
{
cache.addObject(stockQuote.getSymbol(), stockQuote);
}
}
}
}
return stockQuote;
}
All Rights Reserved
Copyright © 2004 SYS-CON Media, Inc.
E-mail: info@sys-con.com
Java and Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. SYS-CON Publications, Inc. is independent of Sun Microsystems, Inc.
|