Search code examples
jakarta-eejbossibm-mqmessage-driven-bean

Controlling concurrency and consumption in MDB


Is there any standard way of controlling concurrency and consumption in an MDB? Every suggestion I've been able to find seem to be application server or resource-adapter specific (e.g. maxSession @ActivationConfigProperty).

The Problem™

We run some relatively heavy analysis jobs on a two-node JBoss setup (EAP 6.3), and want to parallelise jobs as well as impose an upper limit on the number of concurrent jobs so we don't swamp the database server. Jobs are started from a web front-end, and should be started whenever there's a free processing slot - there's no prioritisation or ordering constraints. We use a message queue (IBM WMQ, because of politics) to distribute "start analysis" messages to the nodes.

Current progress

After a lot of fiddling following various suggestions that turned out to be Non-Working Resource-Adapter-Specific Cargo-Cult Misinformation™ :), I thought the problem was solved by defining an EJB pool for the MDB. This does solve the concurrency issue, but unfortunately it seems like a node with no free MDBs still pulls messages of the queue - which can leave one node underutilised and the other fully loaded with a backlog.

If I understand the IBM documentation correctly, this behaviour should be controllable with the readAheadAllowed configuration option, but this doesn't seem to influence my results at all.

So, is there:

  • A Java EE-standard way to control message consumption?
  • A (working) IBM WQ specific configuration option?
  • A JBoss specific way to fix it?
  • Some other smart solution that I haven't thought of?

Alternatively I could probably rework the architecture to use a topic queue, and let each node attempt something along the lines of UPDATE Projects SET Status='inprogress' WHERE Id=42 AND Status='inqueue'; - but I'd rather not go there if I don't have to, mostly because of the Change Requests required for getting the queue changed :)


Solution

  • I ended up using my "Alternatively I could [...]" method - changing the "start-analysis" to a broadcast message, and handling node selection with the status clause in the SQL statement.

    It's a simple solution that doesn't add a lot of extra complexity, and it has turned out to work very well in practice - it has been running in production for about a year by now.