`
hechengrong
  • 浏览: 29493 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

tomcat文件缓存分析[一个bug]

阅读更多

=====================================
apache tomcat中文件的缓存机制
=====================================
一. 环境
 version: apache tomcat 5.5.26
 
二. 缓存机制[ServletContext.getResourceAsStream]
 1. 根据给出的path到缓存中查询CacheEntry; 以下是从ProxyDirContext类中摘出来的方法
  protected CacheEntry cacheLookup(String name) {
   if (cache == null)
    return (null);
   if (name == null)
    name = "";
   for (int i = 0; i < nonCacheable.length; i++) {
    if (name.startsWith(nonCacheable[i])) {
     return (null);
    }
   }
   CacheEntry cacheEntry = cache.lookup(name);
   if (cacheEntry == null) {
    cacheEntry = new CacheEntry();
    cacheEntry.name = name;
    // Load entry
    cacheLoad(cacheEntry);
    //注释:要特别注意cacheLoad这个方法, 它缓存文件最后修改时间时,并没有取真正的时间,仅仅缓存了
    //文件属性对象[这时候的修改时间为-1, 还没有, 只有等到下次对比的时候才取]
   } else {
    if (!validate(cacheEntry)) {
     if (!revalidate(cacheEntry)) {
      //注释: revalidate这个方法要注意,它是用文件的大小和最后修改时间来比较的
      
      cacheUnload(cacheEntry.name);
      return (null);
      //注释: 它清除缓存之后,并没有马上将新的内容加载到缓存中.
     } else {
      cacheEntry.timestamp =
       System.currentTimeMillis() + cacheTTL;
     }
    }
    cacheEntry.accessCount++;
   }
   return (cacheEntry);
  } 
  
  protected void cacheLoad(CacheEntry entry) {

   String name = entry.name;

   // Retrieve missing info
   boolean exists = true;

   //注释:出问题的点就在下面,它只将文件的属性对象缓存了,
   //并没有取文件的最后修改时间[它的初始化值是-1, 只有调用
   //之后,才会取得真正的最后修改时间].
   // Retrieving attributes
   if (entry.attributes == null) {
    try {
     Attributes attributes = dirContext.getAttributes(entry.name);
     if (!(attributes instanceof ResourceAttributes)) {
      entry.attributes =
       new ResourceAttributes(attributes);
     } else {
      entry.attributes = (ResourceAttributes) attributes;
     }
    } catch (NamingException e) {
     exists = false;
    }
   }

   ....
  }
  
 2. 如果找到CacheEntry, 则将CacheEntry.resource返回;
如果没有找到,则到文件系统加载指定的文件;

 从以上的分析来看,它的缓存有以下几个特点:
 > 从缓存中获取的时候,它是根据path获取一个CacheEntry对象,如果有,还需要验证这个对象是否有效,如果无效,就直接删除;
 > 删除缓存的内容时,并不马上将新的内容添加到缓存中,而只是简单的将缓存清空而已;
 > 建立缓存的时候,它将缓存对象[文件或资源]的属性也缓存了[但当时并没有取出最后修改时间]
 > 判断一个缓存对象是否有效的依据是:文件大小和文件的最后修改时间.
 
 由于tomcat在生成缓存对象的时候,只是将缓存对象的属性对象缓存起来,并没有获取"最后修改时间属性", 所以导致下一次对比缓存的
时候,缓存中的"最后修改时间属性"就是当前文件的最后修改时间.
 例如:
 [原始文件, 最后修改时间: 001]
 第一次访问: 缓存不存在, 生成缓存, 并生成缓存属性[缓存属性中的最后修改时间: -1]
 [第一次修改文件, 最后修改时间: 002]
 第二次访问: 缓存存在, 取得缓存对象, 对比时间和大小, 由于缓存属性的最后修改时间为-1, 所以取当前文件的最后修改时间
假设文件大小没有改变,所以就直接使用缓存中的内容[缓存属性中的最后修改时间: 002]
 [第二次修改文件, 最后修改时间: 003]
 第三次访问: 缓存存在,从缓存中取, 由于缓存中的最后修改时间与当前的最后修改时间不一样,所以清缓存;
 [第三次修改文件, 最后修改时间:004]
 第四次访问: 缓存不存在, 重复第一次访问的逻辑
 
 因此, 按以上逻辑, 第2, 5, 8, 11...(3*n-1, n为自然数)次访问的时候会出问题,没有取到最新的内容,而是上一次的缓存结果.
 这个问题的根据原因是:对时间属性的缓存,并没有缓存真正的时间(不知道tomcat出于什么原因,为什么缓存的时候不将最后修改时间
取出来?)
 
三. 说明
 1. CacheEntry上的关键属性:
  > resource或context: 表示缓存的内容
  > attributes: 表示缓存文件的一些属性;
  > name: 缓存文件的path;
 

分享到:
评论

相关推荐

    官方原版tomcat-9.0.29 64位

    Tomcat 9.0.29是Apache Tomcat服务器的一个稳定版本,发布于2019年11月29日。它遵循Java EE 8规范,支持Servlet 4.0、JSP 2.3和EL 3.0等技术。这个版本包含了一系列的bug修复、安全更新和性能改进,确保了更好的...

    apache-tomcat-8.0.44

    Apache Tomcat 8.0.44 是一个广泛使用的开源软件,主要作为Java Servlet和JavaServer Pages (JSP) 的Web应用服务器。Tomcat是Apache软件基金会Jakarta项目的一部分,它实现了Java EE(现在称为Java Platform, ...

    apache-tomcat-9.0.27-apache-tomcat-10.0.27.zip

    首先,Apache Tomcat 9.0.27是9.x系列的一个稳定版本。在该版本中,主要关注的是bug修复、性能优化和安全更新。Tomcat 9支持Java EE 8 Web Profile规范,这包括了对JSF 2.3、JPA 2.2、CDI 2.0等技术的支持。9.0.27...

    apache-tomcat-7.0.79

    Apache Tomcat 7.0.79 是一个广泛使用的开源软件,主要作为Java Servlet和JavaServer Pages(JSP)的容器,以及Java EE Web应用程序的轻量级应用服务器。它由Apache软件基金会开发并维护,是Java社区中的一个重要...

    tomcat8.0.12

    3. `RELEASE-NOTES`:这是一个重要的文档,详细列出了Tomcat 8.0.12相对于前一版本的改进、新功能、已知问题以及bug修复。开发者和管理员应仔细阅读此文件,以便了解可能影响他们应用的任何变化。 4. `RUNNING.txt`...

    tomcatPlugin

    9. **兼容性**:TomcatPlugin应与多个版本的Tomcat服务器兼容,以满足不同环境的需求。 10. **社区支持**:TomcatPlugin通常由开发者社区维护,这意味着用户可以获得最新的更新、bug修复以及来自社区的支持和帮助。...

    apache-tomcat-8.0.52 版本 免安装

    Apache Tomcat是一个实现了Java EE Web组件规范的轻量级应用服务器,特别是Servlet和JSP容器。它由Apache软件基金会维护,是Java生态系统中的关键组成部分,为开发者提供了在Web服务器上运行Java应用的平台。 2. *...

    apache-tomcat-7.0.4.zip

    解压“apache-tomcat-7.0.4.zip”后,你会得到一个包含多个目录和文件的结构。其中,`bin`目录包含了启动和停止Tomcat的脚本,`conf`目录存储配置文件,`webapps`目录是部署Web应用程序的地方,`lib`目录包含了运行...

    apache-tomcat-10.1.0-M8.tar.gz

    在Java Web开发中,Tomcat扮演着至关重要的角色,因为它是一个轻量级的Web服务器和应用服务器,具有高效、稳定和易于管理的特点。 Apache Tomcat的版本命名遵循一定的规则:主版本号(如10)表示重大更新,次要版本...

    tomcat8.0源码

    - **上下文(Context)**:上下文表示一个Web应用程序,它包含了一个或多个应用的WAR文件或目录。 - **连接器(Connector)**:连接器负责监听端口,接收HTTP请求,并将其传递给Catalina进行处理。 3. **部署与启动**...

    tomcat9.0.10

    3. **解压与配置**:下载的`apache-tomcat-9.0.10.zip`文件解压后,你会得到一个包含所有Tomcat组件的目录结构。为了运行Tomcat,你需要配置`conf/server.xml`文件,包括设置端口号、定义应用上下文路径等。同时,...

    apache-tomcat-8.0.47

    Apache Tomcat是一个开源的软件应用服务器,主要用于运行Java Servlet和JavaServer Pages(JSP)应用程序。这个特定的版本,"apache-tomcat-8.0.47",是Tomcat 8系列的一个发行版,它包含了对Java EE 7规范的支持。...

    tomcat_performance_tuning_20071015

    【标题】"Tomcat Performance Tuning 20071015" 是一个由Steve Heckler编写的关于Tomcat服务器性能优化的PPT文档,它深入探讨了如何提升Apache Tomcat在处理Web应用程序时的效率和响应速度。Tomcat是Java Servlet和...

    apache-tomcat-7.0.14-windows-x86.zip

    Apache Tomcat 7.0.14 是一个广泛使用的开源软件,它是一个实现了Java Servlet、JavaServer Pages(JSP)和Java EE的部分规范的Web应用服务器。这个版本是专为Windows x86平台设计的,提供了在Windows操作系统上运行...

    apache-tomcat7,最新版

    总之,Apache Tomcat7是一个强大的Java Web服务器,提供了丰富的功能和高度的可扩展性。熟练掌握其使用和配置,对于任何Java Web开发者来说都是必要的技能。不断更新至最新版本,不仅可以享受新特性,还能保持系统的...

    apache-tomcat-10.0.13-windows-x64位官方版

    8. **版本更新**:从10.0.13版本来看,这可能是Tomcat的一个维护更新,可能包含了bug修复、性能提升或新的功能。定期检查并升级到最新版本,有助于保持系统的安全性和兼容性。 9. **集成开发环境(IDE)支持**:...

    apache-tomcat-8.0.28.rar

    在解压"apache-tomcat-8.0.28.rar"后,你会得到一个名为"apache-tomcat-8.0.28"的目录,其中包含了Tomcat的运行所需的所有文件和目录,例如"bin"目录下的启动和停止脚本、"conf"目录中的配置文件、"webapps"目录用于...

    apache-tomcat-9.0.0.M10-windows-x86

    Apache Tomcat是一个开源软件应用服务器,特别用于运行Java Servlet和JavaServer Pages(JSP)技术。这个特定的版本,"apache-tomcat-9.0.0.M10-windows-x86",是Tomcat 9的一个早期预览版,针对32位Windows操作系统...

Global site tag (gtag.js) - Google Analytics