Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Web Application: How to implement caching techniques?

I am developing a Java web application that bases it behavior through large XML configuration files that are loaded from a web service. As these files are not actually required until a particular section of the application is accessed, they are loaded lazily. When one of these files are required, a query is sent to the webservice to retrieve the corresponding file. As some of the configuration files are likely to be used much, much more often than others I'd like to setup some kind of caching (with maybe a 1 hour expiration time) to avoid requesting the same file over and over.

The files returned by the web service are the same for all users across all sessions. I do not use JSP, JSF or any other fancy framework, just plain servlets.

My question is, what is considered a best practice to implement such a global, static cache within a java Web application? Is a singleton class appropriate, or will there be weird behaviors due to the J2EE containers? Should I expose something somewhere through JNDI? What shall I do so that my cache doesn't get screwed in clustered environments (it's OK, but not necessary, to have one cache per clustered server)?

Given the informations above, Would it be a correct implementation to put an object responsible for caching as a ServletContext attribute?

Note: I do not want to load all of them at startup and be done with it because that would

1). overload the webservice whenever my application starts up
2). The files might change while my application is running, so I would have to requery them anyway
3). I would still need a globally accessible cache, so my question still holds

Update: Using a caching proxy (such as squid) may be a good idea, but each request to the webservice will send rather large XML query in the post Data, which may be different each time. Only the web application really knows that two different calls to the webservice are actually equivalent.

Thanks for your help

like image 752
LordOfThePigs Avatar asked Mar 31 '09 04:03

LordOfThePigs


People also ask

How cache is implemented in web application?

So the application level caching you want to do usually should occur on the web servers to reduce load on the database. As far as what should be cached, the heuristic is items frequently accessed and/or expensive to generate (in terms of database/web server processing/memory).

How do you implement caching?

So the standard way to implement cache is to have a data structure, using which we can access value by a given key in constant time. Now all good, we can save key value pairs in memory and retrieve it whenever we need it.


1 Answers

Here's an example of caching with EhCache. This code is used in several projects to implement ad hoc caching.

1) Put your cache in the global context. (Don't forget to add the listener in WEB.XML).

import net.sf.ehcache.Cache; import net.sf.ehcache.CacheManager;  public class InitializationListener implements ServletContextListener {         @Override     public void contextInitialized(ServletContextEvent sce) {         ServletContext ctx = sce.getServletContext();         CacheManager singletonManager = CacheManager.create();         Cache memoryOnlyCache = new Cache("dbCache", 100, false, true, 86400,86400);         singletonManager.addCache(memoryOnlyCache);         cache = singletonManager.getCache("dbCache");                ctx.setAttribute("dbCache", cache );                } } 

2) Retrieve the cache instance when you need it. i.e. from a servlet:

cache = (Cache) this.getContext().getAttribute("dbCache");

3) Query the cache just before you do an expensive operation.

        Element e = getCache().get(key);         if (e != null) {             result = e.getObjectValue(); // get object from cache         } else {             // Write code to create the object you need to cache, then store it in the cache.             Element resultCacheElement = new Element(key, result);             cache.put(resultCacheElement);          } 

4) Also don't forget to invalidate cached objects when appropriate.

You can find more samples here

like image 146
javito Avatar answered Sep 21 '22 15:09

javito