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:
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
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
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.
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
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
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.