![]() |
Michael Gilfix Online |
Navigation |
Why It's Worth Optimizing Local Web Service InvocationsWhen people typically think of Web Services, they think of remote calls that cross system boundaries and typically networks. Web Services is also typically used with the design philosophy of Service-Oriented Architecture (SOA), which suggests encapsulating a bunch of business logic and function as a callable service with a more granular interface. A huge advantage of Web Services is how is supports a loosely coupled componentization model. This can be a boon for developing flexible, scalable systems that support dynamic selection of function at runtime; Web Services can effectively be used to bind together internal components of the system as well as exposing more granular services. This technique of binding together the system also supports a very flexible packaging model. In J2EE parlance, components can be bundled as multiple WAR files in a single EAR or as a set of EARs, where each EAR contains a single and very self-contained component. The usual concern with this approach of moving one step down in granularity from the service level is one of performance: in the CPU cost and latency of making the Web Service invocation. This is where local Web Services optimization comes in. Within a cluster of application servers, all components can be distributed to each application server; each application server contains a copy and executes all the code for each components. In this example, each component is packaged in its own EAR -this comes with advantages discussed below. When calling shared components, the fronting service or component is configured with a local endpoint is given to the Web Service runtime: This architecture looks as follows: ![]() ... by optimizing local Web Service invocations, the overhead associated with each invocation to the common components, or shared code is dramatically decreased. Note that this invocation still goes through the application server engine and the Web Service is configured to look like a SOAP/HTTP request. The application server must recognize that this is bound for a local destination and optimize the request. Why this approach as opposed to use using Java code or even a Java binding to a WSDL interface? This approach brings several advantages:
In order to support this optimization, application servers must consider several factors. The invocation must not go out to the network port but instead be short cut internally by the Web Service stack. The stack must take into account that components may span different class loaders when passing objects. In the J2EE example, different WAR modules and EAR modules have different class loaders. The ideal optimization would provide a pass by reference mechanism. Thread use is also an issue. The invocation must be performed on a single thread. Otherwise, there's a risk of running out of threads and locking up the system, since the fronting service thread if held while various invocations are made to back-end services. If different threads are used to dispatch requests to those services and the app server runs out of threads, then the fronting service will hang, exacerbating the resource problem and incurring deadlock. These optimizations serve to reduce overhead costs and latency. The WebSphere Application Server supports all these optimizations with the exception of the pass by reference approach, although some steps were taken to cut down the serialization cost. This overhead can further be reduced at design time to sticking to XSD types that correspond directly to Java primitive types, making serialization cheap. This approach was used very successfully in practice in the architecture and design of the Telecom Web Services Server. By Michael Gilfix at 2007-01-18 05:39 | Application Servers | Architecture | Design | SOA | Web Services | Michael Gilfix's blog | login or register to post comments
agree wholeheartedly but with the caveat that......each 'unit' of flexibility comes at the cost of a 'unit' of deployment complexity, and I am not convinced that they are the same cost. Deploying one EAR can be a pain to get correct. Now multiply the potential for error by the number of independent components. And even that assumes a heterogeneous deployment platform. While technically elegant I would caution others to examine the potential impact on documentation, training, and support before starting down such a path. I do love the approach, but I feel that it should be adopted only with caution. By Rhys Ulerich (not verified) at Sun, 2007-01-21 07:44 | login or register to post comments | report as spam
Good pointI agree that it comes with a cost of deployment complexity, and it pays to choose the granularity of the component model wisely to make it worthwhile. However, how much of the complexity is the actual deployment of the EAR itself so much as configuring the dependent resources? Meaning, if you took that function and rolled it up into one big EAR, wouldn't you still have to configure the dependent resources for that function? The counter argument to that is that you might get better resource sharing (of JNDI names, etc.) if it's rolled into a single unit. Providing good EAR deployment defaults goes a long way at reducing this cost; the setup of the resources needs to be done outside the EAR, regardless. |
SearchRecent blog posts
|
What about Apache Tomcat ?
What about Apache Tomcat ?