OSGi is fast becoming the de-facto way to create modular java applications, however when running large scale enterprise applications often the bottleneck becomes the computer itself. Usually the culprits are RAM & CPU, eventually you hit a limit and things just won’t go any faster.
So whats the point in modular code if each computer works in isolation? Yes you may have very flexible software, well design, decoupled and all those other things, but if your not solving issues for your customers then what does it really matter? Remember real artists ship!
dOSGi aims to take all those cool things that OSGi provides an easy way to share them out over your computers, hence the d for distributed. The idea of deploying components and wiring them up as you want, independent of what computer they were run on really does sound like the future, so it was time to boot up eclipse and set myself a challenge. To do a basic evaluation of the performance aspects of dOSGi.
dOSGi ships with a couple of ways to make your computers talk to each other, but the most suited for general comm’s without too much hassle is the web service implementation from CXF. So I decided to see if I can get distributed components talking with this system, and see how fast it is.
The application itself formed a very simple OSGi app, my service has one method to log a report event, this method just prints some information to standard out. A separate project holds the interface definition for my service and 2 more projects are setup to place calls to the service locally and remotely over web services.
dOSGi is built around declarative services within OSGi, my previous work had been with Spring DM so it was a real joy to see how easy declarative services are. I may see how I can wire things with Spring DM at some point, but for now be prepared to create your xml files for wiring things up in your OSGI-INF folder.
Wiring up a local service was easy, as with most OSGi you just declare its interface, implementation and your done, like this:
What I wasn’t prepared for would how easy it would be to turn my local service into a remotely accessible web service, a few property key’s and its done…
Unless you setup your projects properly, your in for a lot of frustration. The errors coming out we’re not helpful so here’s a list of the 2 important things you need to remember to do:
- Include the equinox DS libraries and dependancies, its simple but forgetting to do this means no services get hooked up. However you only find that out when you make a call and get a null pointer.
- If your building, include your OSGI-INF folder in your build.properties, if you forget this all your DS wiring will be missing from you jar file
Invoking services is just as easy as declaring them! You can declare to insert services in your standard DS wiring files, however thanks to an extra file stored at OSGI-INF/remote-service/remote-services.xml you can re-route the calls to remote services.
Now, in all honesty, i’ve got a lot of work left on performance analysis before I can make a full comment on how this all works. The case I have picked out is probably one of the most simple as theres no complex objects, large sizes of objects, exceptions, etc. But it does serve as a start point to answer the question of if dOSGi looks like it could be a workable distributed systems architecture…
My method of testing the reporting system was to run 1000 calls to the reportEvent() function both locally within the same JVM and remotely from another JVM. This serves to test the remote invocation and serialisation functionality without including things like network IO etc.
Note: My actual test function places a call, waits 10ms and then repeats. This was to simulate more realistic call patterns and avoid unfair bias towards the local calls, if for example the network port needs to flush etc. It seemed worthless seeing what a service was like when being DDOS’d!
1000 Local Calls – 10901ms
1000 Remote Calls – 13379ms
If you trim the sleep’s from those calls you can see that the remote calls are around 4 times slower than local invocation.
This is not a scientific test, this is a way for me to see if this technology could be a future building block of modular, distributed systems. I was expecting the time it takes to serialise to xml and back to be a lot worse, but I have to say a 4 times drop in speed is not bad.
As I stated before, when building distributed systems, often you are doing this to avoid problems like CPU, RAM limits so you can accept some performance loss as it may be better than the alternative of waiting for going to disc. For applications that require the highest of performance there are far better ways to solve such problems, but then again you probably don’t need highly modular solutions.
In summary I am really surprised with the performance characteristics of dOSGI, the simplicity with which it works and just how fast you can develop very complicated systems (but maintain tidy modular code). Apache has a binary XML format as well within CXF so hopefully in the future that drops in to give performance gains, in the meantime I think I need to build a more complex solution and test out on some cloud servers.