Category Archives: JMS

JMS: the nitty gritty

In a previous post I explained why using JMS instead of Tridion’s Cache Channel Service is a good idea. Now I will get down to earth and show you how to actually implement it. I’ve picked Apache’s ActiveMQ as JMS server, mostly because it’s free and it works well on Windows. I’m assuming you have Tridion running, with a deployer and a web server which you have configured separately. If your deployer and web site share the same Tridion configuration files, you will not be able to configure JMS successfully! This is because – as you will see – the deployer requires a slightly different storage configuration than the web site. Check the Tridion documentation to see how this can be done.

The architecture looks basically like this:

JMS

The installation consists of the following tasks:

  1. Install ActiveMQ
  2. Change storage configuration of the deployer
  3. Change storage configuration of the web site

1. Installing ActiveMQ

First, download the latest release from http://activemq.apache.org/download.html. In my case, that was ActiveMQ 5.6.0. The software is distributed as a zip file.

Next, unzip the file in a location of your choice. It will create a folder called apache-activemq-5.6.0 (or whatever the version is). Note: it is not an installer, it is the actual server, so you may want to put it in C:\Program Files or something.

Go to apache-activemq-5.6.0\bin\win64 and double click on InstallService.bat.

Go to the services panel. You should now see a service called ‘ActiveMQ’. Start it.

That’s all there is to it. Actually, there are many configuration options for ActiveMQ, but the default config seems to work fine with Tridion.

 

2. Configure the deployer

The Tridion deployer must have an ActiveMQ client installed. The client consists of a number of jar files that can be found in the ActiveMQ folder, under lib. Simply take every jar file in that folder, except slf4j, to Tridion’s lib folder. Slf4j is already installed by Tridion.

You could also use a file called activemq-all-X.X.X.jar, which sits in the root of the ActiveMQ zip that you just downloaded. However, when I did that, the Tridion logging stopped working because of a conflict between log4j versions!

Next, look for the cd_storage_conf.xml and open it in an editor.  You must add a RemoteSynchronization element inside the ObjectCache element like this:

<RemoteSynchronization Queuesize="512">
  <Connector Class="com.tridion.cache.JMSCacheChannelConnector" Topic="Tridion" Strategy="AsyncJMS11">
    <JndiContext>
      <Property Name="java.naming.factory.initial" Value="org.apache.activemq.jndi.ActiveMQInitialContextFactory"/>
      <Property Name="java.naming.provider.url" Value="tcp://SERVER:PORT?soTimeout=5000"/>
      <Property Name="topic.Tridion" Value="TOPIC NAME"/>
    </JndiContext>
  </Connector>
</RemoteSynchronization>

The SERVER is of course the machine where you installed your JMS server. The PORT is the port it’s listening to (defaults to 61616). The TOPIC NAME can be any string. It identifies the ‘queue’ you plan to use. Make sure the deployer uses the same topic name as the web server to which it deploys.

Note that JMS can work with different strategies. They differ in the delivery method (synchronous or – more commonly – asynchronous), the JMS version (1.0 or 1.1) and whether or not they operate within a J2EE environment using Message Driven Beans (you may run into this if you use a JMS service within Websphere, for example).

Tridion’s default strategy is AsyncJMS11. See the Tridion documentation for more information on JMS strategies.

Restart the deployer service to activate the changes. In case of in-process deployment you must restart IIS.

 

3. Configure the web site

The web site needs the same ActiveMQ client  as the deployer, so start by copying those jars to the Tridion lib folder again. The lib folder, by the way, is normally found inside the bin folder of your web application (on .NET) or in the WEB-INF (on Java).

Next up is the cd_storage_conf.xml. It requires usually the same change as the deployer’s storage configuration.

<RemoteSynchronization Queuesize="512">
  <Connector Class="com.tridion.cache.JMSCacheChannelConnector" Topic="Tridion" Strategy="AsyncJMS11">
    <JndiContext>
      <Property Name="java.naming.factory.initial" Value="org.apache.activemq.jndi.ActiveMQInitialContextFactory"/>
      <Property Name="java.naming.provider.url" Value="tcp://SERVER:PORT?soTimeout=5000"/>
      <Property Name="topic.Tridion" Value="TOPIC NAME"/>
    </JndiContext>
  </Connector>
</RemoteSynchronization>
Note that the strategy in the web application can never be set to AsyncJMS10MDB or AsyncJMS11MDB, since message driven beans can only be used for sending messages, not for receiving them.

Restart the web site to activate the changes.

Put it to the test

That’s it. Try it by publishing some content. Be sure to check the cd_core log for exceptions. If you have made a mistake in the configuration, it will normally show up in there.
If you want to learn more about ActiveMQ, check out their web site, or read this blog post by Christian Posta.  Or you can just be satisfied that it works, like I was.

Tridion and JMS: removing another SPOF

When you use Tridion’s content delivery API to retrieve dynamic content, resolve links, etcetera, you are well advised to use the built-in caching mechanism. Without it, every page request would result in dozens of queries on your broker database (or dozens of data files being opened, which is just as bad for performance). With caching, most requests can be handled completely from memory, which makes your site a lot faster.

There is one catch to caching: Tridion being a content management system, it is highly likely that the content and links will change from time to time. That is why Tridion offers a notification system, so that your web application will always show content which is up to date and links that lead to the correct destination.

Actually, Tridion offers not one such notification system, but two. Most implementations use the so-called Cache Channel Service. This is a proprietary service which runs as a windows service or a stand-alone java process. Its job is to notify the broker instances when a new version of an item has been published to the broker repository. The Cache Channel Service uses the RMI protocol to communicate between the different virtual machines (which contain the broker instances).

Although this is certainly the most popular notification mechanism, it has some drawbacks:

  • RMI is not a messaging protocol, so things might go wrong when the Cache Channel Service is temporarily down. Fortunately, Tridion has solved this by some clever programming in the broker, but it is still a work-around which makes the CCS slightly unstable at times.
  • RMI uses unpredictable ports, which means that all ports > 1024 must be open between all your machines running a Tridion broker and the one running the CCS.
  • There is no easy way to handle multiple channels (like a staging site, a live site, a mobile site, development environments, etc). You can only achieve this by running more than one CCS instance, which means running multiple processes, each on a different port, or even running the CCS on multiple machines.
  • The CCS is a single point of failure (SPOF), since it cannot be scaled up.

As a solution architect, I find these disadvantages quite unsettling. Especially the last one: removing single points of failure from a solution is what we architects drool over.

Fortunately, SDL has come up with an alternative notification system. Instead of installing the CCS, you can also install a JMS instance. JMS – Java Message Service – is Java’s messaging system. There are many implementations available, including free ones like Apache’s ActiveMQ.

JMS is designed to pass messages from one application to another. These messages are organized in containers called ‘topics’. Applications can subscribe to a topic. Whenever a message becomes available in this topic, it will be passed on to all subscribing applications.

JMS addresses each of the problems of the Cache Channel Service mentioned above:

  • JMS can work over http on a fixed port (typically 61616, but it can be configured to run on any port including 80)
  • Multiple channels can be accommodated on a single JMS instance by simply configuring extra topics
  • Since JMS works on http, it can easily be accessed through a load balancer. This removes the single point of failure from the architecture.
There is a common idea about JMS, and that is that it would be unsuited for a .NET presentation stack. This idea is incorrect. I can guarantee that the solution will work just as fine if your web site is on IIS. After all, the content broker core is always Java, and it is this core that does the communication through JMS.

Where’s the catch then? Well, there isn’t any, other than the lack of awareness of this solution in the Tridion community, and the lack of configuration examples in Tridion’s product documentation. But with some perseverance, the help of this excellent post by Julian Wraith and – if necessary – the assistance of Tridion customer support, it can certainly be done. The end result is a more stable and more robust solution.