wiki:ConfiguringActiveMQ

Configuring ActiveMQ

Communication in the SEMAINE API passes via ActiveMQ, an open-source message-oriented middleware which implements the Java Message Service (JMS) specification.

We use the publish-subscribe model of JMS for communicating, which is based on the notion of a Topic: components can publish (send) messages to a Topic or subscribe to the topic to receive messages sent to that Topic. In other words, it is a flexible mechanism for n-to-m communication. To establish a communication between two components, it is sufficient for them to use the same Topic name.

ActiveMQ uses a broker -- a messaging server to which all components connect. In previous versions of the SEMAINE API, the activemq server had to be started separately; as of SEMAINE-3.1, there is the option of creating an embedded broker as part of the java process. The main java config file provides a boolean property semaine.use.embedded.broker through which the use of an embedded broker can be switched on or off (see ConfiguringSEMAINE).

Connecting to an external ActiveMQ server

Let us first assume that activemq runs as a separate server. In that case, all components will connect to the activemq server via a URL. By default, the ActiveMQ server uses the "OpenWire" protocol (which for activemq is bound to the protocol prefix tcp:// and port 61616, so that a connection to an activemq server on the local machine corresponds to the URL:

tcp://localhost:61616

This setting can be provided as a global setting to the SEMAINE API as follows:

For java:

java -Djms.url=tcp://localhost:61616 ...

For C++:

# for Mac / Linux:
export CMS_URL=tcp://localhost:61616

rem for Windows:
set CMS_URL=tcp://localhost:61616

Embedded ActiveMQ

If a SEMAINE java process is configured to run an embedded activemq server as part of the java process itself, the communication between the components in that process and the activemq server will be done in memory, which improves performance.

For all other components in the system, nothing changes: they will connect ot this embedded activemq broker in the same way as they connect to an external activemq broker.

Configuring ActiveMQ

All communication in the SEMAINE API passes via ActiveMQ. Since SEMAINE is a real-time system, it is essential to carefully configure ActiveMQ. For the embedded case, there is an ActiveMQ configuration file included in the java classpath: tags/3.1.0/java/src/eu/semaine/jms/activemq.xml. We also provide a reference config file to use (or start from) when running an external ActiveMQ server, in tags/3.1.0/doc/activemq.xml (tested with ActiveMQ 5.4.1 and 5.3.0).

The key problem to be aware of is producer flow control. When a producer is too fast for one of the consumers, the default behaviour of ActiveMQ is to block the producer in the send method until there is enough free space for the slow consumer to receive additional messages. In practice, that looks as if the system had locked up. To avoid this, we configure constantPendingMessageLimitStrategy to keep only the 1000 newest messages for each consumer and to discard the rest.

Changing the port of an embedded ActiveMQ broker

The usual way to change the port on which an ActiveMQ broker listens for connections would be to change the transportConnector setting in the activemq.xml config file. However, to simplify the configuration of embedded brokers, we use the following convention.

If the system property jms.url is present on a java process which is configured to use the embedded broker, the port given in the value of that property is used for the embedded broker to listen to connections from external clients.

For example, starting a java process with

java -Djms.url=tcp://localhost:61617 -Dsemaine.use.embedded.broker=true eu.semaine.system.ComponentRunner ...

allows other components to connect to activemq via port 61617.

Last modified 7 years ago Last modified on 12/14/10 15:26:47