Bookmark this page

Configure Journals and Other Settings

Objectives

  • Configure messaging journals and other messaging subsystem settings.

Configuring the Messaging Journals

Persistence in JMS refers to the ability to guarantee delivery of messages in a topic or queue, even if the JMS provider fails. Typically, JMS implementations use a database for implementing persistence. By default, ActiveMQ uses the file system, and the files that store the messages are referred as journals. To learn more about using messaging persistence with a database in Red Hat JBoss Enterprise Application Platform (JBoss EAP) see the references section.

ActiveMQ message persistence applies to queues marked as durable, and to topics. The topics always need persistence because there could be subscribers pending of start up and receive the messages. ActiveMQ also saves other data to the file system, such as the active subscriber list. There are a few file sets maintained by ActiveMQ but this course only covers the messaging journal.

The ActiveMQ journals are optimized for handling a large volume of messages quickly and reliably. The journal on-disk data structure is similar to the transaction logs used by databases such as PostgreSQL and metadata on file systems such as Linux ext4 and XFS.

Journals have the following properties:

  • The journal consists of a set of files on your machine's file system.

  • Each file is created a fixed size and filled with padding to maximize disk access performance.

  • Messages are appended to the journal. The journal files are read and written as a ring buffer, so space from messages already consumed is reused by new published messages.

  • When one journal file is full, ActiveMQ moves on to the next one. If there are no remaining empty journal files, then ActiveMQ creates one.

  • ActiveMQ has a compaction algorithm which recovers space from previously consumed messages and eliminates fragmentation from the journals. This might leave a few journal files empty and eligible to be removed.

  • The journal supports transactional operations if required, supporting both local and XA transactions.

To maximize ActiveMQ on-disk performance, avoid creating new journal files and running the compaction algorithm. When files have to be created, expanded or deleted, the OS must perform additional I/O operations on file system metadata. If those operations are avoided, then the OS can perform the minimal number of physical I/O operations to read and write application data.

For better performance, you can run load tests or do capacity planning to configure the server=default embedded MOM instance inside the messaging-activemq subsystem with the appropriate number and size of messaging journal files.

The following listing shows all attributes related to the messaging journal from the default Red Hat JBoss Enterprise Application Platform (JBoss EAP) configuration in managed domain mode:

[domain@127.0.0.1:9990 /] cd /profile=full/subsystem=messaging-activemq/​server=default
[domain@127.0.0.1:9990 server=default] :read-resource
{
    "outcome" => "success",
    "result" => {
        ...
        "journal-buffer-size" => undefined,
        "journal-buffer-timeout" => undefined,
        "journal-compact-min-files" => 10,
        "journal-compact-percentage" => 30,
        "journal-file-size" => 10485760,
        "journal-max-io" => undefined,
        "journal-min-files" => 2,
        "journal-pool-files" => -1,
        "journal-sync-non-transactional" => true,
        "journal-sync-transactional" => true,
        "journal-type" => "ASYNCIO",
...output omitted...

As the previous listing shows, the default messaging journal has the journal-min-files property set to two and the journal-file-size property set to 10 MiB. Journal files have the same size and each one can store messages from multiple durable queues and topics.

For example, the following command changes this to nine files of 50 MiB each in standalone server mode:

[standalone@localhost:9990 /] cd /subsystem=messaging-activemq/server=default
[standalone@localhost:9990 server=default] :write-attribute(\
name=journal-min-files, value=9)
[standalone@localhost:9990 server=default] :write-attribute(\
name=journal-file-size, value=52428800)

You can also change the main journal attributes by using the management console. You can access either the full or full-ha profile in a managed domain For example, navigate to Configuration > Profiles > full > Messaging > Server > default and click View, to enter the Configuration page for ActiveMQ. Then click Journal for the messaging journal attributes.

Figure 8.3: JBoss EAP JMS Provider window, messaging journal settings

NIO versus AIO

This course only covers the journal-type attribute from ActiveMQ, which accepts two values:

  • NIO: uses the standard Java NIO API to interface with the file system. This provides extremely good performance and runs on any platform where there is a Java 6+ runtime. JBoss EAP 7 requires at least Java 8.

  • ASYNCIO: uses the native Linux Asynchronous I/O library (AIO). Using AIO typically provides better performance than using Java NIO.

The AIO library requires Linux kernel 2.6 or later and the RPM package libaio. Both are installed by default in Red Hat Enterprise Linux 9. For other Linux distributions, check with the OS vendor.

The default value for the journal-type is ASYNCIO, but if the AIO native library cannot be loaded then ActiveMQ falls back to NIO.

To make sure that JBoss EAP is using the AIO library, read the server instance logs for a message similar to the following:

2016-05-23 15:28:48,994 INFO  [org.apache.activemq.artemis.core.server] (ServerService Thread Pool -- 68) AMQ221012: Using AIO Journal

Other Messaging Settings

An administrator expects to be able to highly customize a production-level MOM, including settings such as security, flow control and redelivery.

ActiveMQ puts those settings outside the destinations, in dedicated configuration elements, because most real-world applications require many destinations with similar settings. This eases administration work and lowers the risk of having inconsistent settings for destinations from the same application.

There are two configuration elements: address-settings and security-settings. The first one contains most settings, and the second one contains only access control attributes.

Both element names rely on a specific wildcard syntax to match a destination name to the element name. The wildcard metacharacters are:

  • # (pound sign): matches anything. For example, the element <address-setting name="#"> matches any destination name, be it a queue or a topic. Another example, stock.us.# matches stock.us.rht and stock.us.nasdaq.rht but not stock.emea.xyz.

  • . (a single period): matches the space between words in a wildcard expression. Most of the time it can be taken as a literal period.

  • * (asterisk): matches a single word. For example, stock.us.* matches stock.us.rht but not stock.us.nasdaq.rht. Another example, stock.*.rht matches stock.us.rht and stock.emea.rht but not stock.us.nasdaq.rht.

To make an address-settings and security-settings match a single destination name, use the full destination name as the element name.

Be aware that the destination name is not the JNDI name. It is the name used internally by ActiveMQ to refer to the destination. For an embedded ActiveMQ inside JBoss EAP, the internal name is the object name prefixed by jms.queue. for a jms-queue resource or by jms.topic. for a jms-topic resource. Notice the dot at the end of both prefixes.

A jms-topic gets a suffix based on the subscriber ID, so an address-setting referring to a jms-topic should always add the suffix #.

The following table shows the name of a destination resource and the name for an address-setting that match that destination specifically:

ActiveMQ destination nameActiveMQ address-setting name
jms-queue=MyQueue address-settings=jms.queue.MyQueue
jms-topic=MyTopic address-settings=jms.topic.MyTopic.#

An address-setting can configure a number of different features, see the JBoss EAP product documentation for description and example usages for each of its attributes. The following examples are included only as syntax examples and they use some attributes related to flow control.

  • The following example matches only the queue called jms.queue.Volatile and limits memory usage for all messages to 100 KiB. If more messages are published that would increase memory use above that threshold, then the new messages are silently discarded:

[domain@localhost:9990 /] cd /profile=full/subsystem=messaging-activemq/server=default
[domain@localhost:9990 server=default] ./address-setting=jms.queue.Volatile:add(\
max-size-bytes=102400, address-full-policy=DROP)
  • The following example matches all destinations from the sensors application (they all follow a naming convention having the app.sensors prefix) and limits memory usage for each destination to 150 KiB. Instead of discarding messages, publishers are prevented from publishing more messages until a few messages are consumed and memory is released:

[domain@localhost:9990 /] cd \
/profile=full/subsystem=messaging-activemq/server=default
[domain@localhost:9990 server=default] ./address-setting=jms.queue.app.sensors.*:add(\
max-size-bytes=153600, address-full-policy=BLOCK)

Two important caveats when configuring ActiveMQ address-settings are:

  1. Many independent features are configured by the same object. When creating an address-setting object focused on a single feature, such as in the previous examples, attributes related to other features get their default values. This might have unexpected side effects, such as a feature that was enabled for all destinations in the default JBoss EAP settings becoming disabled for a few destinations.

  2. Multiple address-settings objects can match the same destination. The most specific match usually overrides less specific ones. Test carefully whether the merged configuration has the expected behavior.

To create and configure address-setting objects by using the management console, navigate to Configuration > Profiles > full > Messaging > Server > default > Destinations and click View. Then click Adress Settings to access the Address Settings panel.

Figure 8.4: JBoss EAP Messaging Provider - Address Settings page

Messaging Security

Messaging security in JBoss EAP deals with both the embedded MOM, that is, ActiveMQ, and the JMS API:

  • The MOM settings define how to authenticate local and remote clients, and which permissions to grant those clients for different destinations.

  • The JMS API defines how to pass credentials from the client to the MOM.

You configure the security for the embedded MOM as attributes for the server=default object inside the messaging-activemq subsystem. The security-domain attribute selects the JBoss EAP security domain used to authenticate client user credentials and fetch its roles.

The default configuration points to the other security domain, which validates user credentials using the ApplicationRealm configured in either the standalone.xml or the host.xml file. For more information about configuring users and roles in the ApplicationRealm, see the Securing JBoss EAP chapter later in this course.

Security is not enforced for applications connecting to the embedded ActiveMQ because the default settings have the override-in-vm-security attribute set to true. Unless this attribute is changed to false, only remote clients have to provide authentication credentials and are subject to authorization checks.

Most production environments require changing default messaging-activemq subsystem configurations to use a different security realm, backed by a database or LDAP server. They probably require enabling authentication from local clients.

To configure permissions for messaging destinations, the administrator configures security-setting objects. Those objects act as address-setting objects by using their names as wildcards to match internal ActiveMQ destination names.

A security-setting object has child objects of type role whose attributes define the permissions held by the named role. The standard JBoss EAP configuration defines a single security-setting=# that contains a single role=guest child that allows any user to publish and consume messages on any destination.

The following command inspects the default security-setting to show the roles specified by the object:

[standalone@localhost:9990 /] cd /subsystem=messaging-activemq/server=default
[standalone@localhost:9990 server=default] ./security-setting=#:read-resource
{
    "outcome" => "success",
    "result" => {"role" => {"guest" => undefined}}
}

The previous output shows that only the guest role was assigned permissions by the default security-setting.

To show the permissions assigned to the role, inspect the role=guest child, as in the following example:

[standalone@localhost:9990 server=default] ./security-setting=#/role=guest:read-resource
{
    "outcome" => "success",
    "result" => {
        "consume" => true,
        "create-durable-queue" => false,
        "create-non-durable-queue" => true,
        "delete-durable-queue" => false,
        "delete-non-durable-queue" => true,
        "manage" => false,
        "send" => true
    }
}

You can also pass the recursive=true argument to the read-resource operation on the security-setting:

[standalone@localhost:9990 server=default] ./security-setting=#:read-resource(\
recursive=true)
{
    "outcome" => "success",
    "result" => {"role" => {"guest" => {
        "consume" => true,
        "create-durable-queue" => false,
        "create-non-durable-queue" => true,
        "delete-durable-queue" => false,
        "delete-non-durable-queue" => true,
        "manage" => false,
        "send" => true
    }}}
}

Be aware that a single security-setting object might provide permissions for many roles, and multiple security-setting objects might match the same destination. Different from an address-setting object, where multiple matches can affect the same destination, the most specific security-setting is used alone. This way a more specific security-setting might deny permissions granted by a more generic one.

Production environments might require the removal of the default permissions assigned to the guest role to implement the secure by default philosophy.

[standalone@localhost:9990 server=default] ./security-setting=#/role=guest:remove

The following example shows how to add permissions to a specific role:

[standalone@localhost:9990 server=default] ./security-setting=#/role=sender:add(\
send=true)

The previous example shows how to add the sender role permission to publish messages to any destination.

Specific permissions, such as send and consume, and their meanings, are presented later in this course in the Securing JBoss EAP chapter.

Handling Message Delivery Failures

One important aspect of MOM management is handling failures to consume messages. Delivery failures might impact performance because a consumer might become stuck in a loop trying to consume the same message over and over, and generating errors for each attempt to process the message contents.

This scenario might happen because messages that were not acknowledged as consumed are not discarded; the messages are left in the destination, to be consumed again later. This is similar to a database rolling back a failed transaction to ensure data consistency. The message reading operation is undone because its enclosing transaction was aborted.

Retrying might be required to allow the application to recover from unexpected failures.

If the failure happens only with some messages and not others, then it is helpful to get the failed messages out of the way. This saves hardware resources to process the messages that were not affected by the current issues and allows those messages that generated failures to be dealt with later.

For example, an application that processes payments from an online store can accept three payment options: credit card, bank transfers, and gift cards. Processing credit card payments requires calling an external web service. This service sometimes experiences technical difficulties, but other payment options are not affected and they do not need to wait until the credit card service is back online.

ActiveMQ address-setting objects allow the administrator to define:

  • A time delay to redeliver a failed message by using the redelivery-delay attribute.

  • A destination to forward the message after a number of failed delivery attempts, by using the max-delivery-attempts and dead-letter-address attributes.

The default messaging-activemq settings include the following address setting:

[standalone@localhost:9990 server=default] ./address-setting=#:read-resource
{
    "outcome" => "success",
    "result" => {
        ...output omitted...
        "dead-letter-address" => "jms.queue.DLQ",
        ...output omitted...
        "max-delivery-attempts" => 10,
        ...output omitted...
        "redelivery-delay" => 0L,
        ...output omitted...

This means that for all destinations (the address-setting object name is #), messages that fail to be consumed after 10 attempts (max-delivery-attempts), are moved to the jms.queue.DLQ destination (dead-letter-address). There is zero delay between delivery attempts (redelivery-delay).

Important

Remember that the destination names used to match an address-setting and for the dead-letter-address attribute are not JNDI names as seen by the JEE application. They are not the name of the destination resources as seen by the management CLI. They are internal ActiveMQ destination addresses.

The rules for generating ActiveMQ internal names were presented earlier in this chapter. Another way to get a destination internal name is by using the queue-address runtime attribute in the jms-queue or jms-topic objects.

Sorting messages from many applications in the same default dead-letter queue (DLQ) is probably not easy and most applications require a custom address-setting object specifying a different redelivery policy.

For example, to have a 5-second delay between delivery attempts from the jms-queue=MyQueue destination and moving messages to jms-queue=MyDLQ after three attempts, use the following command:

[standalone@localhost:9990 server=default] ./address-setting=jms.queue.MyQueue:add(\
redelivery-delay=5000, dead-letter-address=jms.queue.MyDLQ, max-delivery-attempts=3)

Some messages might require different treatment if they are not consumed in a certain time. For this case, ActiveMQ allows to configure an expiry queue using the expiry-address attribute from the address-setting object. The JMS API specifies how an application might provide a message expiry interval. An administrator can also use the expiry-delay attribute to define a default interval for messages to expire. This default interval does not override the one specified by the application.

For example, to have a 20-minute default expiry interval (1200000ms) for messages from the jms-queue=MyQueue destination and move messages that took longer to consume to jms-queue=MyExpiry, use the following command:

[standalone@localhost:9990 server=default] ./address-setting=jms.queue.MyQueue:add(\
expiry-delay=1200000, expiry-address=jms.queue.MyExpiry)

If both redelivery and expiry options from the two previous examples are required, a single address-setting object has to be created merging all attributes. Note that address-setting names must be unique, even if multiple `address-setting`object names can match the same destination internal address.

References

For more information about messaging journals, see the Messaging Journal Persistence Using the Default File Journal section in the Configuring Single-node Messaging Systems chapter in the Red Hat Red Hat Jboss Enterprise Application Platform 7.4 Configuring Messaging documentation at https://access.redhat.com/documentation/en-us/red_hat_jboss_enterprise_application_platform/7.4/html-single/configuring_messaging/index#messaging_journal_persistence_using_the_default_file_journal

For more information about messaging persistence with a database, see the Messaging Journal Persistence Using a JDBC Database section in the Configuring Single-node Messaging Systems chapter in the Red Hat Red Hat Jboss Enterprise Application Platform 7.4 Configuring Messaging documentation at https://access.redhat.com/documentation/en-us/red_hat_jboss_enterprise_application_platform/7.4/html-single/configuring_messaging/index#messaging_journal_persistence_using_a_jdbc_database

For more information about the address setings, refer to the Address Settings section in the Configuring Single-node Messaging Systems chapter in the Red Hat Red Hat Jboss Enterprise Application Platform 7.4 Configuring Messaging documentation at https://access.redhat.com/documentation/en-us/red_hat_jboss_enterprise_application_platform/7.4/html-single/configuring_messaging/index#configure_address_settings

Revision: ad248-7.4-18a9db2