While remoting is often used in Enterprise Java applications due to the fact that other systems and applications need to be invoked, unnecessary remoting is an important cause of badly performing Enterprise Java applications.
Therefore this issue can manifest itself in a number of different ways:
- Invoking a EJB remotely when a local call is available (also a case of incorrect usage of Java EE).
- Invoking an external application when the functionality is available within Java itself. The code below was discovered in an production source code:
Runtime.getRuntime().exec("d:\\path\\to\\bin\\sleep.exe " + nbSecond);
The same functionality could have been gotten with a simple:
Thread.sleep(nbSecond * 1000);
- Using SOAP when RMI would suffice. SOAP invocations are typically 10 to 20 times slower than the equivalent RMI invocation, depending upon the SOAP framework used, the network speed, and the time taken on the server by the invoked method itself. See Comparison of performance of web services, WS-security, RMI, and RMI-SSL by Juric, Rozman, Brumen, Colnaric, and Hericko for a scientific case study. In any case, using SOAP can be a case of unnecessary use of XML, which in turn causes excessive memory usage.
- Invoking a lot of small method calls (fine grained) instead of one large method call (coarse grained), thereby incurring the remote method invocation overhead multiple times. The Transfer Object pattern was invented to solve this problem in JavaEE where it was especially prevalent in EJB 1.x entity beans.
In some cases an architecture is designed with remoting built-in for some anticipated future need that never occurs. For example, a colleague of mine has encountered an application split into two projects: a services layer (providing access to a mainframe) designed for multiple front-ends that could be accessed through a SOAP interface and a web interface invoking the services layer. In the end no other front-ends were built and the whole system was deployed within one application server cluster. The benefits of remoting were not used, but the performance hit was still there. A typical case of YAGNI!
The same thing can be seen in previous version of J2EE; EJB 1.x had only remote beans because that would allow clustering to improve availability and performance, even though that was not always needed. Similarly I can't really get excited about WSRP; I shudder to think about the performance of a portal (not one of my favorite technologies in any case) that invokes it portlets over a SOAP interface.
Anyway, sometimes you just have to deal with remoting. In that case, these tips may help you mitigate the damage:
- First of all, make sure you really need remoting.
- Choose your remoting technology wisely. Don't use SOAP because all the cool kids are doing it. 😉 Consider alternatives like Hessian (an efficient binary protocol), Burlap (a XML version of Hessian), Spring's HTTP Invokers (a Java-only binary protocol), or RMI. Write a benchmark for your situation to help you decide.
- Avoid invoking fine grained methods remotely. Use the Facade pattern to cluster them together to form coarsed grained methods.
- If remoting is needed for only a part of your use cases, consider exposing your business functionality using different technologies. For example, the Spring framework allows functionality to be invoked by a Java method call while that same functionality is also exposed as a service by an Exporter.
Remoting has its uses and its advantages, just be aware of its implications for the performance of your application!