Outside of Rob Brooks-Bilson's blog, there's not a lot of information on digging down into the ColdFusion's internal implementation of ehCache. I recently spent some time getting the built-in ehCache implementation to replicate across multiple nodes using RMI. Overall the process isn't that difficult, but due to the lack of information out there, it took me much longer to figure out the exact steps necessary to get things work.
NOTE: ColdFusion 10 added the ability to specify a specific ehcache.xml file on a Per Application basis using the this.cache.configfile value. Unfortunately, you can not use this method to configure replication. You will need to replace the default ehcache.xml that ships with ColdFusion.
- The first thing you want to do is backup your default ehcache.xml file. This will be in your CF10's install folder at cfusion/lib/ehcache.xml. I recommend renaming the file ehcache.xml.bak. If you run into issues, you can always restore the original configuration.
- Open the ehcache.xml in your favorite editor.
- Find the CacheManagerPeerProvider comment. After that comment there's a sample <cacheManagerPeerProviderFactory /> element. Below that, insert the following element:
<!-- In order for this rule to work, you must: * Configure the operating system to use multicast * Open up UDP on port 4446 in the firewall --> <cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory" properties="peerDiscovery=automatic,multicastGroupAddress=220.127.116.11,multicastGroupPort=4446,timeToLive=1" propertySeparator="," />
- Right below that, you should see the CacheManagerPeerListener comment. After the comment, there's a sample <CacheManagerPeerListener /> element. Below that, insert the following element:
<!-- In order for this rule to work, you must: * Open up TCP on port 40001 & 40002 in the firewall --> <cacheManagerPeerListenerFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory" properties="port=40001,remoteObjectPort=40002" />
- Lastly, go down to the <defaultCache /> element and add the <cacheEventListenerFactory /> element. For example:
<!-- Mandatory Default Cache configuration. These settings will be applied to caches created programmtically using CacheManager.add(String cacheName). The defaultCache has an implicit name "default" which is a reserved cache name. --> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="86400" timeToLiveSeconds="86400" overflowToDisk="false" diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000" diskPersistent="false" diskExpiryThreadIntervalSeconds="3600" memoryStoreEvictionPolicy="LRU" clearOnFlush="true" statistics="true" > <!-- apply the replication listener to all caches created by ColdFusion --> <cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" /> </defaultCache>
- Save your changes.
- Restart ColdFusion.
- Open up the following firewall rules:
- UDP: port 4446
- TCP: ports 40001-40002
In order for this all to work, your server must be configured for multicast. In Redhat, this isn't a standard config, so there's some additional steps you may need to do.
While ehCache does allow you to set up a peer-to-peer configuration, it's very unwieldy and won't work well with ColdFusion, unless you explicitly use named regions in all your code. The reason multicast is really required, is because it's the only method in which ehCache replication works without having to manually specify the name of each region to replicate.
I hope this helps someone out!