Re: Socket factories with JERI / JERI vs. JRMP performance penalties
Mark Brouwer <[email protected]> Thu, 6 Dec 2007 17:00:35 +0100
| Newsgroups | gmane.comp.java.sun.jini |
|---|---|
| Message-ID | <[email protected]> |
Hi Martin, Cornelius, Martin (DWBI) wrote: > First i'd just like to report that i was finally sucessfull in > creating JERI connections that obey read and write timeouts by using NIO > based Socket factories, although that was somewhat tricky. The reason it > didn't work 'out of the box' was, that JERI internally tests if the > socket it has got from the SocketFactory has an underlying NIO > SocketChannel by calling Socket.getChannel(). If this returns not null, > JERI uses this SocketChannel directly, and does not call > Socket.getInputStream() neither Socket.getOutputStream(). > > My Socket factory is coded following the guidance given in > http://java.sun.com/javase/6/docs/technotes/guides/rmi/socketfactory/index.html, > means it has it's timeout functionality wrapped into the streams > returned by Socket.getInputStream() and Socket.getInputStream(). > Initially, the coding of my Sockets internally delegated > Socket.getChannel() to the underlying socket obtained via > SocketChannel.socket(). As this returned the SocketChannel, JERI simply > bypassed my functionality. The simple solution was, to return null from > my own Socket.getChannel(), instead of delegating this method. This way > i could trick JERI to use my streams. The spec for java.net.Socket states that when a Socket returns non-null for getChannel() that the stream retuned by getInputStream and getOutputStream must/should delegate all of its operations to the channel. So Jini ERI is correct in its usage of the returned socket, and in case you want to implement some features in the streams returned there is unfortunately no other way than returning null for getChannel() and loosing NIO based handling from the Jini ERI viewpoint. Or of course you should be able to implement it at the channel level, which you found out ain't that easy. > I also tried another way, i.e., to return a subclass of SocketChannel > > from Socket.getChannell, that has it's own implementations of the > various read() and write() methods provided by SocketChannel. However, > this gets complicated, as Jeri internally uses Selectors with a > SocketChannel. Unfortunately, inside NIO it is somewhere checked whether > the SocketChannel worked on is derived from sun.nio.ch.SelChImpl, what > means i would have to implement this interface in my subclass of > SocketChannel. As this interface is sun-internal, i think it is not > portable to use it in application code, and gave up with this idea. I forgot the details but when I was implementing a NIO based HTTPS server I ran into similar problems that there seems to be no easy way to subclass SocketChannel to implement some additional behavior without reimplementing almost the complete stack. > Anyways, all this tricks with socket factories give me a little > 'hacky' feeling. Having roundtrip timeout constraints supported directly > by JERI would look much cleaner in my opinion. No disagreement here. > Now comes the more interesting part: > > When playing around with SocketFactories, i made somewhat alarming > observations w.r.t. performance: Transferring a single large chunk of > data with JERI took about 10 TIMES as long as transferring it with JRMP. > With client and server on the same (otherwise unloaded) linux-2.6.17 > machine, actual throuput with JERI is about 6 MByte per second, with > JRMP it's about 60 Mbyte per second. First i thought, the reason was my > SocketFactories, but the same factor shows up with the standard built-in > socket factories ! I guess this is caused by JERI's multiplexing > features, which may show another picture if multiple concurrent calls > are made. However, a factor of 10 in this quite simple test seems > extremely high, doesn't it ? I'd wonder if anybody else has reported > this, or if its a mistake in my test program. > BTW, under windows (on the same machine), performance is about 20% > better, but the ratio between JRMP and JERI is the same. It has been a very, very long time I've done any comparison between Jini ERI and JRMP (2002) as I completely rely on Jini ERI features and my experience was that it was indeed slower but for remote method invocations that had no parameters and return objects (with ping it was IIRC factor ~2 for one particular setup). This is mainly due to very much necessary 'overhead' related to all the features you won't find in JRMP. My experience was that as soon as marshalling came into play performance was getting closer to each other as both JRMP and Jini ERI have about the same kind of stuff to do there. Based on you mentioning throughput in MBytes I think your performance test doesn't have the typical remote method invocations I was conducting then. Could you tell a bit more about the kind of invocations you are making and whether these took place concurrently, etc. Another thing not 100% clear to me is whether you were doing the tests with your own socket factories or not? In case you were not using socket factories did you set the system property "com.sun.jini.jeri.tcp.useNIO" to true. One reason to use socket factories is to force usage of NIO. Also I'm curious whether you had GC logging enabled to see whether there are some anomalies between the 2 tests and whether you monitored the load of your systems for both tests. Another thing that might be handy to know is how many cores the systems had. A factor 10 is a lot though. One last question is what would the typical usage be in the field you want to utilize it? -- Mark -------------------------------------------------------------------------- Getting Started: http://www.jini.org/wiki/Category:Getting_Started Community Web Site: http://jini.org jini-users Archive: http://archives.java.sun.com/archives/jini-users.html Unsubscribing: email "signoff JINI-USERS" to [email protected]