当前位置:  开发笔记 > 编程语言 > 正文

Java Web应用程序:如何实现缓存技术?

如何解决《JavaWeb应用程序:如何实现缓存技术?》经验,为你挑选了3个好方法。

我正在开发一个Java Web应用程序,它通过从Web服务加载的大型XML配置文件来实现它的行为.由于在访问应用程序的特定部分之前实际上不需要这些文件,因此它们会被懒惰地加载.当需要其中一个文件时,会向Web服务发送查询以检索相应的文件.由于某些配置文件可能会被大量使用,更经常比别人我想建立某种形式的缓存(有可能1个小时的过期时间),以避免一遍又一遍请求相同的文件.

对于所有会话中的所有用户,Web服务返回的文件都是相同的.我不使用JSP,JSF或任何其他花哨的框架,只是简单的servlet.

我的问题是,在Java Web应用程序中实现这样一个全局静态缓存的最佳实践是什么?单例类是否合适,或者由于J2EE容器会有奇怪的行为吗?我应该通过JNDI在某处暴露某些东西吗?我该怎么做才能使我的缓存不会在集群环境中搞砸(每个集群服务器有一个缓存可以,但不是必需的)?

鉴于上面的信息,将一个负责缓存的对象作为ServletContext属性是否是正确的实现?

注意:我不想在启动时加载所有这些并完成它因为那样

1).每当我的应用程序启动时重载webservice
2).我的应用程序运行时文件可能会更改,所以无论如何我都要重新查询它们
3).我仍然需要一个全局可访问的缓存,所以我的问题仍然存在

更新:使用缓存代理(例如squid)可能是一个好主意,但是对webservice的每个请求都会在post Data中发送相当大的XML查询,每次都可能不同.只有Web应用程序才真正知道对Web服务的两个不同调用实际上是等效的.

谢谢你的帮助



1> javito..:

以下是使用EhCache进行缓存的示例.此代码在多个项目中用于实现临时缓存.

1)将缓存放在全局上下文中.(不要忘记在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)在需要时检索缓存实例.即来自servlet:

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

3)在执行昂贵的操作之前查询缓存.

        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)也不要忘记在适当的时候使缓存的对象无效.

你可以在这里找到更多样品



2> Rastislav Ko..:

您的问题包含几个单独的问题.让我们慢慢开始.ServletContext是一个可以存储缓存句柄的好地方.但是你需要为每个服务器实例提供缓存.应该没问题.如果要在更大范围内注册缓存,请考虑将其注册到JNDI中.

缓存的问题.基本上,您是通过webservice检索xml.如果您通过HTTP访问此Web服务,您可以在您的旁边安装简单的HTTP代理服务器来处理xml的缓存.下一步是在某种本地对象缓存中缓存已解析的xml.每个服务器可以存在此缓存而没有任何问题.在第二种情况下,EHCache将做得很好.在这种情况下,处理链将是这样的Client - http request -> servlet -> look into local cache - if not cached -> look into http proxy (xml files) -> do proxy job (http to webservice).

优点:

每个服务器实例的本地缓存,仅包含来自请求的xmls的对象

一个http代理在与我们的webapp相同的硬件上运行.

可以在不为xml文件添加新的http代理的情况下扩展webapp.

缺点:

下一级基础设施

+1点失败(http代理)

更复杂的部署

更新:不要忘记始终将HTTP HEAD请求发送到代理中以确保缓存是最新的.



3> Tim O'Brien..:

选项#1:使用开源缓存库,如EHCache

当有许多优秀的开源替代方案可以插入并开始使用时,不要实现自己的缓存.实现自己的缓存要比大多数人意识到的要复杂得多,如果你不确切知道自己在做什么,那么你就可以轻松地重新开发轮子并解决一些非常棘手的问题.

我推荐EHCache它是在Apache许可下.您需要查看EHCace代码示例.

选项#2:使用Squid

更容易解决您的问题的方法是使用Squid ...将Squid置于请求缓存数据的进程和发出请求的系统之间:http://www.squid-cache.org/

推荐阅读
wurtjq
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有