Glassfish MQ: Secure, database backed GlassFish MQ for high volume applications

By | February 8, 2017

GlassFish MQ is a very powerful messaging server solution if correctly configured. By default the MQ server is defined to store the content of queues on files on disk, is accessible through insecure connections and has lots of limitations for message size or number of consumers/producers associated with a queue.
This default setup is OK in case of some small project or for development but in case of a high volume enterprise application they are no longer feasible.
We can modify the behavior of GlassFish MQ by setting several parameters in the config.properties of an MQ instance. Note that each domain defined in GlassFish has a different associated MQ instance. If we have a domain named “demo” the associated MQ server can be configured under:


/opt/glassfish3/glassfish/domains/demo/imq/instances/imqbroker/props/config.properties

Bellow we will discuss each section that has to be added to the configuration file.

STEP 1: General parameters
The first group of parameters contains some general setup parameters:


# general setup
imq.instanceconfig.version=300
imq.portmapper.hostname=localhost
imq.jms.tcp.port=7115
imq.message.max_size=200m
imq.jmsra.managed=true

where:
imq.portmapper.hostname = MQ hostname
imq.jms.tcp.port = the jms tcp port to which MQ is accessible
imq.message.max_size = the maximum size of a message that can be added to a queue
imq.jmsra.managed = is always set to true on a managed MQ broker

STEP 2: Configure MQ to use an external database as data storage
As we mentioned, by default MQ uses file stores to store the content of the queues. In enterprise system with bigger traffic this is not longer an option in case we need to:
– replicate data
– recover data
– store big messages
– need to have a persistent storage of data across application restarts

The solution is to specify the persistence jdbc parameters:


#JDBC properties
imq.persist.store=jdbc
imq.persist.jdbc.dbVendor=oracle
imq.persist.jdbc.oracle.user=myuser
imq.persist.jdbc.oracle.password=password
imq.persist.jdbc.oracle.needpassword=true
imq.persist.jdbc.oracle.property.url=jdbc\:oracle\:thin\:@localhost\:1521/mydatabase
imq.persist.jdbc.brokerid=IMQBROKER

where:
imq.persist.store = persistence storage protocol (jdbc)
imq.persist.jdbc.dbVendor = database vendor (oracle)
imq.persist.jdbc.oracle.user = database user (myuser)
imq.persist.jdbc.oracle.password = database user password (password)
imq.persist.jdbc.oracle.needpassword = password is mandatory (true)
imq.persist.jdbc.oracle.property.url= connection string url (jdbc\:oracle\:thin\:@localhost\:1521/mydatabase)
imq.persist.jdbc.brokerid= broker ID (IMQBROKER)

As a result of this configuration after restart of the domain you will notice a series of new tables prefixed with MQ appearing under mydatabase tablespace.
In this tables all the queues with their messages plus a lot of locks and other parameters will be stored.

Note: Special attention must be given to MQVER41SIMQBROKER. Here a lock with the instance fully qualified name is stored.


imqbroker:localhost:7010

In case of environments that are replicated across sites this become very important. One must either use the same name on both site (same broker name and the same host name), or an SQL script must truncate this entry before starting the domain on the remote site. Failure to do so will result in the MQ server not being started due to this lock.

STEP 3: Fine tune the auto-create properties

This is a very important step in case auto-created queues are used. The most usual queue that is auto-created is the dead message queue (mq.sys.dmq).


# auto-create properties
imq.autocreate.destination.maxTotalMsgBytes=-1
imq.autocreate.destination.maxNumMsgs=-1
imq.autocreate.destination.maxNumProducers=-1
imq.autocreate.destination.maxBytesPerMsg=-1

where:
imq.autocreate.destination.maxTotalMsgBytes = maximum size in bytes of all the message from a queue (-1 is unlimited)
imq.autocreate.destination.maxNumMsgs = maximum number of messages from a queue (-1 is unlimited)
imq.autocreate.destination.maxNumProducers = maximum number of producers associated with a queue (-1 is unlimited)
imq.autocreate.destination.maxBytesPerMsg = maximum size in bytes of a message from a queue (-1 is unlimited)

It is important to set this parameters to a bigger value than defaults wich are very small. For example imq.autocreate.destination.maxTotalMsgBytes by default is 10MB.
In case when our MQ is already configured as having the persistence store in an external database a value of -1 (unlimited) is indicated.

STEP 4: Configure secure access to MQ

By default the GlassFish MQ is accessible through insecure connection. Naturally in an enterprise environment we should allow only ssl connections if possible.


# security properties
imq.ssljms.tls.port=7114
imq.service.activelist=admin,ssljms
imq.keystore.file.name=keystore.jks
imq.keystore.file.dirpath=/cert/mq/etc
imq.keystore.password=keystorepassword

where:
imq.ssljms.tls.port= the tls post for secure connections
imq.service.activelist= the connection types that are allowed ( admin = admin, ssljms = secure jms connection ,jms = insecure jms connection). In production environment we must not allow “jms”.
imq.keystore.file.name= name of the keystore where the server certificate is kept. By default the alias of the certificate is “sjsa”. This can be modified from GlassFish admin console.
imq.keystore.file.dirpath= the path to the keystore
imq.keystore.password= the keystore password

Restart the domain and the new configurations will be loaded.

[paypal_donation_button]

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.