Service-oriented architecture (SOA) allows businesses to enable legacy systems and new software products as a service to a wider audience by way of the Internet. Web services technology is the cornerstone of SOA implementation, which involves complex business transactions between various business entities. XML processing, the core component of web services technology, involves SOAP processing, XML binding, and XML parsing. Understanding various traits of the Web Services Description Language (WSDL) is important for gaining better performance and scalability of web services. This article shows how to implement high performance web services using the Java API for XML Web Services (JAX-WS) 2.0 and provides feature and performance comparisons with the Java API for XML-Based RPC (JAX-RPC) 1.1. The performance data in this article will help you design highly performant web services. Web Services Stack Overview
Sun's initial implementation of web services was called JAX-RPC 1.1 (JSR 101). This was a standards-based implementation, but the binding and parsing layers underneath it were proprietary. Additionally, JAX-RPC 1.1 does not completely cover schema specification. Sun's newer version of the web services stack, JAX-WS 2.0 (JSR 224), is completely standards based. Even the binding layer, the Java Architecture for XML Binding (JAXB, JSR 222), and the parsing layer, the Streaming API for XML (StAX, JSR 173) are standards based and also support schema specification 100 percent.
Figure 1 represents the JAX-RPC and JAX-WS implementations. The advantages with JAX-WS are ease of development and high performance. As the performance of JAXB and StAX improves, so does the performance of the JAX-WS stack. For this reason, the JAX-WS stack is referred to as an integrated stack. Web Services Performance
Understanding web services performance is important because it allows the developer to design and implement efficient enterprise web services for performance and scalability. You can measure the performance of the web services stack in two ways, depending on your deployment model: end-to-end performance and endpoint performance. End-to-End Performance If a web service deployment involves the client and server stack, then measurements in the performance tests should include both of these components. This requires a thick client, which exercises the client side of the web services stack. Figure 2 illustrates end-to-end performance, in which a client driver uses a thick web services stack to send and receive SOAP requests.
Endpoint performance In this case, the only concern is the endpoint, that is, the server-side performance. For these measurements, you can use a thin client with an HTTP driver to stress the endpoint. Figure 3 illustrates endpoint performance, in which a client uses a thin HTTP driver to send and receive SOAP requests.
This article focuses on performance data for end-to-end performance, with only occasional references to endpoint performance. The WSTest Benchmark
This article uses the WSTest benchmark to measure JAX-RPC and JAX-WS performance. WSTest is a client-server microbenchmark developed at Sun Microsystems to measure the performance of the Java technology web services stack. WSTest is designed to mimic real-world web service processing. Typically, any web service application needs a container to run. WSTest can be deployed either on GlassFish or Tomcat. This benchmark is highly configurable to meet the needs of the real-world simulation such as number of clients, addition of test cases, percentage mix of web services processing (for example, the percentage of time you would like a particular use case to be executed), and so on. This is very similar to an application server that deploys web services and concurrently processes a number of SOAP requests from users. WSTest reports the number of transactions per second and the average response time. Performance Measurements
This section discusses primitive performance, primitive array performance, payload performance, and binding performance in web services. Primitive Performance Primitives such as Consider the WSDL sample shown in WSDL Sample 1. WSDL Sample 1
WSDL Sample 1 shows the integer primitive echoing back and forth between client and server. Code Sample 1 shows the corresponding web service implementation code. Code Sample 1
Similarly, changing the different primitives in the WSDL produces the corresponding service implementation code. Table 1 compares the Java technology primitives generated for JAX-RPC 1.1 and JAX-WS 2.0 for the corresponding XSD primitive types defined in the WSDL.
The graph in Figure 4 shows the performance of XSD primitives. The x-axis indicates the XSD primitives such as
Note that there is not much performance difference when choosing from The graph in Figure 4 implies that all the primitives will give the same performance when the binding layer is not stressed. Primitive Array Performance As you may have noted in the example of primitives performance, you are not stressing the binding layer. If you send only the primitives back and forth, then the performance of primitives is masked by the performance of the container, such as doing the connection handling, scheduling the tasks, and so on. This section shows how primitive arrays perform when the binding layer is stressed. This is a way of moving the magnifying lens from the container layer to the binding layer. Consider WSDL Sample 2. WSDL Sample 2
The WSDL code in WSDL Sample 2 shows an example for sending and receiving the array of integer primitives. Code Sample 2 shows the corresponding web service implementation code for JAX-RPC 1.1. Code Sample 2
Code Sample 3 shows the corresponding web service implementation code for JAX-WS 2.0. Code Sample 3
Table 2 shows the distinction between JAX-RPC 1.1 and JAX-WS 2.0
at the service endpoint for various Java technology primitive arrays
generated for the corresponding XSD primitives with
Note that JAX-RPC 1.1 generates indexed arrays, whereas JAX-WS 2.0
generates The graph in Figure 5 shows the performance of XSD primitive
arrays. The x-axis indicates XSD primitive arrays such as
As you can see, once you start stressing the binding layer, the
performance of primitives varies. Also note that JAX-WS 2.0 performs
better in all cases and shows great improvement -- nearly double in
some cases -- in Payload Performance Web services performance is proportional to the amount of payload sent: The more payload you send, the more processing is required for the serialization and deserialization, as well as for binding and parsing. This has a considerable effect on performance. Consider a hypothetical case in which you have to send and receive items with the item structure shown in Code Sample 4. For example, in a supply-chain management system, you would request line items for a particular order or to process a batch of items. Code Sample 4
The graph in Figure 6 shows the performance of JAX-WS relative to JAX-RPC in percentage as the payload size -- that is, the number of items -- varies. The x-axis represents the number of items sent and received, and the y-axis represents the percentage of JAX-WS throughput compared to that of JAX-RPC. In this use case, a transaction is defined as the sending and receiving of an array of items.
The graph in Figure 6 indicates that, at payloads over 100 items, JAX-WS throughput almost doubles the performance of JAX-RPC, whereas at payloads lower than 100 items, JAX-WS and JAX-RPC give similar results. In general, JAX-WS performance is better than that of JAX-RPC at larger payloads. Binding Performance There are multiple ways to handle XML documents in Java web services. This section compares the performance of document-handling JAXB and Document Object Model (DOM) binding for an XML document, specifically an industry-standard 100 kilobyte Universal Business Language (UBL) invoice. JAXB Binding JAXB binding provides a way to convert from Java technology objects to XML and from XML to Java technology objects. The syntax for JAXB binding is shown in WSDL Sample 3, in which an element named WSDL Sample 3
When the WSDL sample in Code Sample 5 is compiled using Code Sample 5
JAXB binding provides several advantages: ease of development, hidden code complexity, lack of boilerplate code, and better performance than nonschema binding. All the developer needs to do is to access the generated JAXB Java class methods for accessing XML content. One disadvantage with JAXB binding is that the generated Java classes are coupled to the schema defined in the WSDL, which makes the JAXB binding approach harder for writing generic code. DOM Binding DOM binding provides a way to convert from a DOM tree to XML and from XML to a DOM tree. The syntax for DOM binding is shown in Code Sample 6, in which an element named WSDL Sample 4
When compiled using Code Sample 6
The advantage of DOM binding is that it allows the developer to write more generic and extendable programs. The disadvantages of DOM binding are that it requires the developer to write more complex code depending on the schema and requires the developer to write more boilerplate code for navigating the DOM tree, which results in reduced performance. Note that in Code Sample 6, only the infrastructural performance is measured; that is, no user code or business logic is involved. In this use case, a transaction is the sending and receiving of a 100 kilobyte UBL invoice XML document. For the graph in Figure 7, the x-axis represents the binding type, and the y-axis represents the throughput. Note: Figure 7 shows the graph for endpoint performance, meaning that it measures only the server-side web services stack.
The graph in Figure 7 illustrates that JAXB binding performs significantly better than does DOM binding. Also, note that the performance of JAX-WS is much better than that of JAX-RPC. In addition, the performance of JAX-WS is even more visible in the case of DOM binding. Summary
To conclude,
For More Information
Acknowledgments
I would like to thank Sameer Tyagi, Santiago Pericas-Geertsen, and Geneviève Duboscq for their valuable feedback and comments on this article. About the Author
Bharath Mundlapudi is a staff engineer in the Java Performance Engineering Group, Java SE, at Sun Microsystems and focuses mainly on XML and web services performance. He currently leads benchmark development for web services, and he measures and improves the performance and scalability of the web services stack in GlassFish on Symmetric Multiprocessing (SMP) and Chip Multithreading (CMT) systems. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|