Reputation: 793
Below is my scenario from Application perspective.
We have 2 applications (.war) files will be running in a same instance of Application server (mostly Tomcat 8), In production we may deploy App1 on 100 servers and App2 only on 50 server out of those 100 (The App2 does not need to be distributed so much)
Now this 2 applications (.war) depends on a common custom jar (some utility classes)
I am planning to use Jcache API and hazelcast implementation in our apps. I have added following dependency in my pom.xml
<!-- JSR 107 JCache -->
<dependency>
<groupId>javax.cache</groupId>
<artifactId>cache-api</artifactId>
<version>1.0.0</version>
</dependency>
<!-- Hazelcast dependency -->
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId>
<version>3.4</version>
</dependency>
Plan is to write a utility CacheManager in this common custom jar which will be shared by App1 and App2.
I am planning to use only the hazelcast server provider as I am doing in-memory cluster i.e. the caching will be in application memory.
Below is the snippet of my code.
public class PPCacheManager {
// Loads the default CacheProvider (HazelCast) from hazelcast.xml which is
// in classpath
private static CachingProvider defaultCachingProvider = Caching.getCachingProvider(); //
// Loads the default CacheManager from hazelcast.xml which is in classpath
private static CacheManager defaultCacheManager = defaultCachingProvider.getCacheManager();
// Some more code goes here...
My hazelast.xml
<hazelcast xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.hazelcast.com/schema/config
http://www.hazelcast.com/schema/config/hazelcast-config-3.4.xsd"
xmlns="http://www.hazelcast.com/schema/config">
<cache name="commonClientCache">
<key-type class-name="java.lang.String"></key-type>
<value-type class-name="java.lang.Object"></value-type>
<statistics-enabled>true</statistics-enabled>
<management-enabled>true</management-enabled>
<read-through>true</read-through>
</cache>
</hazelcast>
Now I have several question around this approach.
Is this a good way to implement the in memory caching (currently we are not looking for cluster caching), should this code be in the common custom jar or somewhere else?
There is some master data from DB which I am planning to load (both applications need this data) so not sure how and where I should load this data into memory. Note: I do not want to do lazy loading; I want to load this master data very first.
Where should I add the cache shutdown code to avoid memory leak issues, as this cache is shared by both the applications.
Also by implementing this approach will I have 2 copies of cache each for application or a single copy will be shared across both?
I have already implemented this approach in my application and from Hazelcast management console I can see that there is only 1 cache is created but it says GET is executed on this cache twice.
Upvotes: 0
Views: 2323
Reputation: 574
Hazelcast is the perfect solution for what you are trying to do. Definitely no lazy loading. You don't need anything like that if you have shared memory.
As far, as how many instances you'd have inside one (Tomcat) JVM, you'd have two if you instantiate Hazelcast twice. It'd autoincrement the port. However both will belong to the same cluster (you call "cache"), as long as the cluster name is the same. So other than looking a little silly (sharding on a single JVM), you are fine. To avoid it, you can configure one of the wars to instantiate a HazelcastClient. The utility jar can be the same. It should all be in some e.g. Spring config - which every war would have its own copy of. Or you can put that config into two external directories and add to the catalina classpath.
The shutdown code belongs to the same place you instantiated Hazelcast i.e. your two wars will have two shutdown calls. You can do it in Spring's destroy() of any of your high-level config (or autowired) beans or put it in the Web App session listener.
Upvotes: 0