{{ !articles[0].partner.isSponsoringArticle ? "Platinum" : "Portal" }} Partner
java,enterprise-integration,java ee,jms,tips and tricks,activemq,geronimo

True Power of Java EE and JMS: Distributed Computations!

Back in 2011 I was writing a PhD about evaluating and measuring quality of Web Services compositions. I had a system where I focued on evaluating WS-BPEL processes (but the framework I designed was extremely flexible and supports any business scenario technology).

The system (called Measurement System DIES) is a Java EE application. It is designed in a distributed manner which makes scaling out and distributing computations very easy.

Out of pure curiosity, I decided to do stress tests. Apache Geronimo did not survive this nor did the embedded ActiveMQ. After I killed Geronimo and started it again all queues stopped working... I had to install brand new instance of Geronimo.

But thanks to Java EE capabilities and the distributed nature of my system I was able to overcome this problem. See how I did it with JMS and distributed computations!

The EJB module of my application

Most of the work performed by my system is done, of course, in EJB module. The EJB module of my application consists of the following (among many other things of course):

  • Queue for execution orders - each execution of a WS-BPEL process instance may last minutes (I have a 10 minutes timeout set up),
  • Queue for asynchronous computing of quality and performance score of each activity trace - this task usually takes up to 4 seconds to complete (most of the time spent here is to query external services like geolocation services),
  • Timer for computing statistics - every 10 seconds I retrieve all completed instances which are not yet analysed and conduct some statistical computations.

The development environment

While developing my system I used 1 box  for everything:

  1. Apache Geronimo with my Java EE application and embedded ActiveMQ server
  2. Apache ODE as an WS-BPEL execution engine
  3. IBM DB2 pureXML

New Machine(s)

I managed to get a second machine. Based on that I decided to distribute my components this way:

1st computer:
  1. Apache Geronimo with my Java EE application with Timer but without Queue components
  2. IBM DB2 pureXML
  3. Apache ODE as an execution engine
2nd computer:
  1. Apache Geronimo with EJB module with Queue components
  2. Standalone ActiveMQ
Ideally I would need 2 more machines:
  • 3rd for IBM DB2 pureXML database
  • 4th for Apache ODE
But having 2 machines was enough.

Distributing components

Here is what I did:

  1. I split my EJB components. I moved my two queues into a separate project and deployed them to Apache Geronimo installed on the second machine. I decided to leave the Timer component in the original EJB project.
  2. I downloaded a standalone ActiveMQ server and installed it on the second machine.
  3. Finally I configured connection factories for both Apache Geronimos. I used the wizard offered by Geronimo's Admin Console - it was childishly simple! I use application-wide JMS resources and just compared the generated deployment plans with the ones I already had. It turned out that I had to add 1 line to my deployment plans - the external server url. NICE! This is how the enterprise configuration should look like!
Rerunning the stress test again

I re-ran my stress test. Both Geronimos and ActiveMQ survived :)

What was the improvement rate? Hard to say... In Java when you add, subtract, multiply or divide NaN by any other number you still get NaN. I know one thing for sure, the first configuration did not survive the stress test :)


Always keep in mind that some day your system will have to be distributed or scaled out. At the design stage it's far more easier to introduce basic enterprise architectural patterns and concepts than to introduce them during the maintenance phase (when, for example, task distribution would have a huge impact on the whole system).

{{ tag }}, {{tag}},

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}
{{ parent.authors[0].realName || parent.author}}

{{ parent.authors[0].tagline || parent.tagline }}

{{ parent.views }} ViewsClicks