Overhead on RMI protocol

I'm using RMI as a way to invoke methods over a LAN. That's works fine, but when I measure the network traffic I can see a tremendous overhead on the networks packets.
For example: if I invoke a simple remote method like,

boolean run( )

I can see that 4 packets travel through the network, the invocation of run, the acknowlegdment, the boolean returned by run and the acknowlegdment. The total size of the TCP/IP packets is about 600 bytes.

This size is too much for the systems we are developing, so we are evaluating changing to sockets (I mean, implementing a specific protocol for our application).

My question is, there is a way to reduce the RMI overhead (some paremeters, some classes we can use) ?
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Mick BarryJava DeveloperCommented:
Not that I'm aware of, RMI just has a lot of overhead. Thats the trade off for its power.

Have you tried testing the network load multiple times?  From what I understand about RMI, the first invocation of the run() method could very easily cost more in bandwidth than subsequent invocations.
It's all a matter of load against development time.

You would be able to develop your own client server protocol which uses tokens, and binary streams to send data between components over the network...  However, this will take ages, and will not be as secure or portable as using plain RMI...

If you have the time, you can write your own stuff...  But 9 times out of 10, it's better to use standard packages and methodologies like RMI...

It has to be said that 600bytes is not very much data to be sending across a network...

Why is this size data a problem?


Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Learn Ruby Fundamentals

This course will introduce you to Ruby, as well as teach you about classes, methods, variables, data structures, loops, enumerable methods, and finishing touches.

pgiustoAuthor Commented:
I'm OK 600 bytes is not very much data. The problem is that our client application, according to the user input, interact with the server, 8 to 9 times per minute.
We are thinking on 100 workstations running the software, and the network is also used by other 50 workstations that puts files and other stuff on the bandwidth. So we made numbers and decided that don't want to install anything that can cause a problem on the bandwidth.
100 workstations, calling 10 times per minute (600bytes)

== 600,000bytes per minute

== 4,800,000bits per minute

100 Base T network = 100,000,000 bits per second

== 6,000,000,000 bits per minute

so it will be consuming less than 1% of the bandwidth of the network...

or less than 10% if you are on an old 10 base T network...

Am I wrong?

(Note:  My maths is lousy, so that may be inaccurate or poorly worked out)
pgiustoAuthor Commented:
No, you are rigth.
We are on a 10 base T network. The systems has to be installed on South America (so, sorry for my english) and the costs of changing to a 100MB network has to be balanced to the cost of refining the developping.
Maybe look at cutting down the # of client/server interactions per minute then?

10% of the bandwidth is probably quite a large amount...  I have no experience with how much of the network is usually used...

The other way to handle it, I suppose, if you cannot live with that kind of overhead, is to code a multi-threaded server that listens on a particular port for a small message to activate the remote process.  Some questions, though:

1.  What, precisely, does the run() method do?  Does it really have no arguments?  Does it really only return a boolean?  Why do you need to 1,000 times per minute?  I can't understand what the use case is.

2.  Do you need confirmation?  That is to say, do you need to make sure that the connection was successful?  The fact that you're returning a boolean suggests that you probably do.  That's more overhead.  From what little I know about networking, you might actually be fairly efficient at 600 bytes, believe it or not.
There are two types of sockets that you can custom-code a server to listen for, each with their own downsides:

1.  UDP/IP Sockets, (implemented with a java.net.DatagramSocket(),) are very efficient in terms of the amount of data sent, and are bidirectional, but are neither sequenced, reliable, or unduplicated.  This means that they're not GUARANTEED to arrive, nor are multiple packets sent via a Datagram Socket guaranteed to arrive in transmission order.

2.  TCP/IP Sockets, (implemented with java.net.Socket(),) are bidirectional, sequenced, reliable, and unduplicated, but necessarily involve more overhead for precisely those reasons.  Still, since you're probably going to need confirmation your message has arrived, as well as the returned boolean to indicate success, you'll probably need that.

IF you can't fight your problem with a broader network pipe, and you can't decrease the number of connections/minute, then this is the only way I can see to go.  I apologize if the Socket Stuff is old hat, by the way :)

Oh, one more thing:  I did find something out on the net.  Out at devshed.com I found a post that discussed BEA WebLogic:  It appears they custom-code their own implementation of RMI to reduce network overhead by only using a single socket for all RMI calls:


So there's one possible way to ameliorate the problem:  Buy BEA's VM, for the tens of thousands of dollars they charge.

(I didn't say it was a GOOD solutions :D )
This goes through several Design Patterns that might cut your network access down:

This is quite a cool read as well (though I'm not sure how relevant it is)

Basically, what they seem to suggest to me is;

If you are making calls like

getUsername( id ) ;
getFirstName( id ) ;
getLastName( id ) ;
getLastLogin( id ) ;

etc, then by creating a wrapper class like:

class UserDetails implements Serializable
  String username ;
  String firstName ;
  String lastName ;
  Date lastLogin ;

and having only two calls; "getUserDetails() ;" and "setUserDetails( UserDetails det ) ;"

You might actually cut down on network usage, as all of the handshaking will only have to be done once, rather than doing it again, and again for each field you require...


pgiustoAuthor Commented:

Ok, run method is only part of the protocol, to show you an example. The client calls "remoteObject.setUserInput(Object o) and then "remoteObject.run( )". Finally it tests the return code of "run" to know if everything goes right or wrong (in this case it calls "remoteObject.getErrorCode( )" to know aboot the nature of the error)

We substitute this protocol with a wrapper that calls the three method in only one method:

int run(Object o);

So we reduce the RMI overhead 66%, without changind the logic of the client nor the server.

Tim Yates:

You have right. Until today, I have designed the systems not considering the protocol or the fisical network behind it. It's time for redesign it, at least the API the server exposes.
Glad I could help :-)

Good luck with the redesign :-)
pgiustoAuthor Commented:
OK. Thanks to everybody, especially SuperKarateMonkey and TimYates. I give the points to Tim, but both of you were very helpful.
Good luck! :-)
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.