温馨提示×

JSP在Ubuntu上如何实现缓存优化

小樊
38
2025-12-10 06:59:48
栏目: 编程语言

JSP在Ubuntu上的缓存优化实践

一 前端与协议层缓存

  • 设置浏览器与CDN可缓存的响应头:对静态资源与长期不变的页面使用Cache-Control: public, max-age=31536000(1年)并配合ETag/Last-Modified;对需要频繁更新的页面使用no-cachemax-age=0, must-revalidate;对登录后个性化页面使用private。在JSP中可直接写入:
    <%
      response.setHeader("Cache-Control", "public, max-age=31536000");
      response.setDateHeader("Expires", System.currentTimeMillis() + 31536000L*1000);
    %>
    
  • 使用Servlet过滤器统一设置缓存策略,便于按路径/类型批量控制:
    public class CacheFilter implements Filter {
        public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
                throws IOException, ServletException {
            HttpServletResponse r = (HttpServletResponse) res;
            String uri = ((HttpServletRequest)req).getRequestURI();
            if (uri.endsWith(".js") || uri.endsWith(".css") || uri.contains("/static/")) {
                r.setHeader("Cache-Control", "public, max-age=31536000");
                r.setDateHeader("Expires", System.currentTimeMillis() + 31536000L*1000);
            } else {
                r.setHeader("Cache-Control", "no-cache, must-revalidate");
            }
            chain.doFilter(req, res);
        }
        public void init(FilterConfig c) {}
        public void destroy() {}
    }
    
    web.xml中映射:*.jsp, /static/*等路径。该做法便于与CDN协同,降低源站压力。

二 页面与片段缓存

  • 使用JSTL c:cache对页面片段做缓存(适用于变动频率不同的区域,如侧边栏、页脚、热点数据块)。示例:
    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
    <c:cache var="sidebar" scope="page" time="3600" unit="second">
        <!-- 计算或查询较耗时的片段 -->
        <div>热点内容或导航</div>
    </c:cache>
    <c:out value="${sidebar}" escapeXml="false"/>
    
    提示:c:cache属于JSTL,需引入JSTL库;对高度个性化内容避免使用片段缓存。

三 数据层与应用层缓存

  • 引入Ehcache 3Guava Cache缓存业务数据,减少重复计算与数据库访问:
    • Maven依赖(示例):
      <dependency>
        <groupId>org.ehcache</groupId>
        <artifactId>ehcache</artifactId>
        <version>3.9.6</version>
      </dependency>
      
    • 代码示例(简化):
      CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder().build(true);
      Cache<String,String> cache = cacheManager.createCache("viewCache",
          CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, String.class,
              ResourcePoolsBuilder.heap(1000)).build());
      
      String key = "hotData";
      String data = cache.get(key);
      if (data == null) {
          data = loadDataFromService(); // 代价高的获取逻辑
          cache.put(key, data);
      }
      // 使用 data 渲染页面
      
    结合TTL/最大条目等策略,命中率与一致性可按业务权衡。

四 操作系统与反向代理层优化

  • 利用Linux Page Cache:JSP编译结果(Servlet类与JSP生成的Java文件)与静态资源由内核自动缓存,通常无需额外代码。保持合理的脏页写回参数有助于吞吐与稳定性(示例值,需结合负载测试微调):
    vm.vfs_cache_pressure = 50
    vm.dirty_ratio = 10
    vm.dirty_background_ratio = 5
    # 执行:sudo sysctl -p 使配置生效
    
  • Nginx侧启用Gzip压缩反向代理缓存,对可缓存内容进行边缘缓存,进一步降低Tomcat/JSP压力:
    • Gzip示例:
      gzip on;
      gzip_types text/html text/css application/javascript application/json;
      
    • 反向代理缓存示例:
      proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=STATIC:10m inactive=60m;
      server {
        location /static/ {
          proxy_cache STATIC;
          proxy_pass http://127.0.0.1:8080;
        }
      }
      
    同时检查防火墙/重写规则,避免不必要的延迟与缓存穿透。

五 落地配置与验证

  • 建议的缓存分层与示例值
    层级 目标 建议策略 示例值
    浏览器/CDN 减少回源 强缓存长期静态资源 Cache-Control: public, max-age=31536000
    Nginx 边缘缓存与压缩 静态资源与可缓存接口 Gzip;proxy_cache
    Tomcat/JSP 降低编译与渲染开销 启用JSP预编译;减少Java脚本片段 jspc/mvn插件;MVC分层
    应用数据 减少重复计算与DB压力 Ehcache/Guava本地缓存 TTL=60–300s;最大条目按内存评估
    操作系统 提升文件访问吞吐 合理利用Page Cache vm.vfs_cache_pressure=50 等
  • 验证与观测
    • 响应头检查:curl -I 查看Cache-Control/Expires/ETag是否符合预期。
    • 命中与性能:观察命中率首字节时间TTFB页面渲染时间;结合业务日志与监控告警。
    • 避免副作用:对登录态/个性化内容禁用或缩短前端缓存;数据缓存设置合理失效与更新策略,必要时主动失效。

0