Tag Archives: hazelcast

Clustering wicket apps

After fooling around with other methods, we finally accepted the advice I got on the Wicket IRC channel and used Terracotta to cluster our Wicket-based apps running under Jetty. It turned out to be straightforward to implement.

The first thing to do was to add the Terracotta dependencies to our pom.xml.

<dependency>
	<groupId>org.terracotta.session</groupId>
	<artifactId>terracotta-session</artifactId>
	<version>1.1.1</version>
</dependency>

<dependency>
	<groupId>org.terracotta</groupId>
	<artifactId>terracotta-toolkit-1.1-runtime</artifactId>
	<version>2.0.0</version>
</dependency>

Then you just need to add a Terracotta filter to the jetty WebAppContext as follows:

FilterHolder tcFilterHolder = new FilterHolder(TerracottaJetty61xSessionFilter.class);
tcFilterHolder.setInitParameter("tcConfigUrl", "terracotta:9510,terracotta2:9510");
context.addFilter(tcFilterHolder, "/*", Handler.ALL);

That’s it. Terracotta will cluster the session (in the example we’re using two terracotta servers called “terracotta” and “terracotta2” – a main server and a standby).

We’re using a HAProxy load-balancer with session affinity to load-balance and failover the wicket apps. Note that we are only clustering the session and not the Wicket PageMapStore. This means that if the app fails over, the browser back-button will not work correctly after a failover. Since failover should only occur rarely, if ever, we don’t see the need to cluster the PageMapStore (although this is not hard either) and incur the network cost of replicating the PageMapStore.

Hazelcast distributed locks for easy fault tolerance

Hazelcast (hazelcast.com) provides an easy way to implement distributed locking to allow your applications to run multiple, fault-tolerant instances without worrying about issues related concurrent access to shared resources (like files, databases or whatever).

try {
	java.util.concurrent.locks.Lock lock = Hazelcast.getLock("mylock");
	while (true) {
		lock.lock();
		try {
			// do some work involving access to shared resources
		} finally {
			lock.unlock();
		}
	}
} finally {
	Hazelcast.shutdown();
}

We have an SMS server which retrieved mail messages from a POP3 mailbox, entered them to a database and then delivered via the Clickatell messaging gateway. Making it run multiple instances concurrently would have been a headache since it would involve various issues relating to transactions across the POP3 and the Clickatell interfaces. It was a whole lot easier to wrap the business logic with a hazelcast lock and let it run on two servers. The beauty of hazelcast is that it just works – since the default configuration uses multicast to detect other members of the cluster, there’s no additional infrastructure – just add the jar to your application and off you go. We might still implement Zookeeper or Terracotta in future, but both of them require more infrastructure (i.e. dedicated (virtual) servers) and configuration.
Postscript: I had occasional hangs with Hazelcast 1.8.4 which caused me to switch to Zookeeper. As expected, Zookeeper was a lot harder to use than Hazelcast – you need Zookeeper installed on 3 servers. There’s no official java client, just some recipes and I found an implementation of Zookeeper locks called Cages on google code. For a java developer, Hazelcast is obviously way easier to use. Anyway, after upgrading to Hazelcast version 1.8.5, the hang problem went away so I happily went back to using Hazelcast. We’re also now using the distributed queues – works great so far.