- 268 -
12.2 Message Reduction
Lets look at a simple example of reducing message calls. For later infrastructure comparison, we will use three different distributed-application infrastructures, CORBA , RMI, and a proprietary
distribution mechanism using plain sockets and serialization see Proprietary Communications
Infrastructures . In the example, I present a simple server object that supports only three instance
variables and three methods to set those instance variables.
Proprietary Communications Infrastructures
You can easily create your own communication mechanisms by connecting two processes using standard sockets. Creating two-way connections with
Socket
s and
ServerSocket
s is very straightforward. For basic communication, you decide on your own
communication protocol, possibly using serialization to handle passing objects across the communication channel.
However, using proprietary communications is not a wise thing to do, and can be a severe maintenance overhead unless your communication and distribution requirements are
simple. I occasionally use proprietary communications for testing purposes and for comparison against other communications infrastructures, as I have done in this chapter.
In this chapter, I use a simple generic communication infrastructure that automatically handles remotely invoking methods: basically, a stripped-down version of RMI. I
generate a server skeleton and client proxy using reflection to identify all the public methods of the distributable class. Then I copy the RMI communication protocol which
consists of passing method identifiers and parameters from proxies to server objects identified by their own identifiers. The only other item required is a lookup mechanism,
which again is quite simple to add as a remotely accessible table. The whole infrastructure is in one fairly simple class,
tuning.distrib.custom.Generate
, which is available from the Examples link on this books catalog page,
http:www.oreilly.comcatalogjavapt .
12.2.1 CORBA Example
The CORBA IDL definition is quite simple:
module tuning { module distrib {
module corba { interface ServerObject {
void setBooleanin boolean flag; void setNumberin long i;
void setStringin string obj; }; }; }; };
The server class implementation for this IDL definition is:
package tuning.distrib.corba; public class ServerObjectImpl
extends _ServerObjectImplBase {
- 269 -
boolean bool; int num;
String string; public void setBooleanboolean b {bool = b;}
public void setNumberint i {num = i;} public void setStringString s {string = s;}
}
All the support classes are generated using the idlj utility. For JDK 1.3, this generates interfaces
ServerObject
and
ServerObjectOperations
; skeleton classes
_ServerObjectImplBase
and
_ServerObjectStub
; and server object assistant classes
ServerObjectHelper
and
ServerObjectHolder
. In addition, I define a
main
method that installs an instantiation of the server object in the name service and then remains alive to serve client requests. All classes are
defined in the
tuning.distrib.corba
package. My client simply resolves the server object from the name service, obtaining a proxy for the server,
and then calls the three methods and sets the three instance variables. For the test, I repeat the method calls a number of times to obtain average measurements.
The optimization to reduce the number of method calls is extremely simple. Just add one method, which sets all three instance variables in one call, i.e., adding the following IDL definition:
void setAllin boolean flag, in long i, in string obj;
The corresponding method is added to the server class:
public void setAllboolean b, int i, String s {
bool = b; num = i; string = s; }
The result is that the single method call requires one-third of the network transfers and takes one- third of the time, compared to the triple method calls see
Section 12.3 .
12.2.2 RMI Example
The RMI implementation is essentially the same. The server-object interface with optimized method is defined as:
package tuning.distrib.rmi; import java.rmi.Remote;
import java.rmi.RemoteException; public interface ServerObject
extends Remote {
public abstract void setBooleanboolean flag throws RemoteException;
public abstract void setNumberint i throws RemoteException;
public abstract void setStringString obj throws RemoteException;
public abstract void setAllboolean flag, int i, String obj throws RemoteException;
}
- 270 - The RMI server-object implementation is the same as the CORBA version, except that it extends
UnicastRemoteObject
, implements
ServerObject
, and defines the methods as throwing
RemoteException
. All the support classes are generated using the rmic utility. For JDK 1.3, this generates skeleton classes
ServerObjectImpl_Skel
and
ServerObjectImpl_Stub
. In addition, I define a
main
method that sets a security manager and installs an instantiation of the server object in the name service. All classes are defined in the
tuning.distrib.rmi
package. Once again, the result is that the single method call requires one-third of the network transfers and
takes one-third of the time, compared to the triple method calls see Section 12.3
.
12.2.3 Proprietary Communications Layer