使用
Java 缓存系统缓存频繁查看的数据

使用 Java 技术的 Web 开发人员可以使用缓存实用程序快速提升他们的应用程序的性能。Java 缓存系统(Java Caching System,JCS)是一个用于 Java 应用程序的强大分布式缓存系统,它是拥有简单 API 的高度可配置的工具。本文将概述 JCS 并展示如何使用它来提高 Web 应用程序的速度。

0 评论:

Kellen
F. Bombardier
, 软件工程师, IBM

2008 年 12 月 29 日

  • 内容

许多 Web 应用程序会根据桌面应用程序重新编写;理想情况下,这些应用程序的速度和可伸缩性应该与桌面版本一样。几乎所有 Web 应用程序都可以从速度方面的增长获益。缓存被频繁查看但很少更改的数据是一种减少用户等待时间的有效方式。一个实用程序可以帮您实现这个目标,它使用简单易用的 API 来轻松处理数据缓存。开放源码 JCS(即一个 Apache Jakarta 项目)就是这样一种工具。本文将说明如何配置和使用 JCS 来缓存 Web 应用程序的数据。

JCS 概述

JCS 是一个用 Java 语言编写的缓存系统,可以使用它来创建 Java 桌面和 Web 应用程序。它提供了在缓存器中存储数据、从缓存器中删除数据等方便机制。

使用 JCS 可以在各种指定的数据区域 中存储缓存数据。JCS 定义了 4 种类型的核心区域:内存区域、磁盘区域、外围区域和远程区域。可以结合使用这些核心区域以在如何存储缓存数据、将缓存数据存储在什么地方等方面获得更大的灵活性。您可以指定首次使用哪个区域,以及发生故障时转移到哪个区域。

内存区域

内存区域是一个使用最近最少算法(Least Recently Used,LRU)的纯内存缓存区域。当内存缓存区域满时,LRU 会首先删除最近最少使用的缓存数据。这个数据区域执行良好,大多数 JCS 用户将它指定为最先使用的默认缓存区域。

JCS 的可插入控制器

JCS 通过组合缓存器(Composite Cache)让使用多个区域进行缓存存储变得很简单。组合缓存器为缓存区域提供了一个可插入控制器。组合缓存器仔细处理复杂的任务,即确定何时以及如何使用每个缓存区域。JCS 将完成大部分复杂的工作,开发人员只需关心获取和设置缓存。

磁盘区域

磁盘区域是在 Web 服务器的文件磁盘上缓存数据。为了提高性能,JCS 在文件磁盘上存储实际缓存数据的同时,会在内存中存储缓存数据键。在首先使用内存区域的典型 JCS 配置中,任何无法在内存区域中保存的数据都会写入磁盘区域中。

外围区域

外围区域提供一种可配置方式来在多台服务器之间分发缓存数据。缓存数据服务器必须有一个开放的用于侦听的端口,而且必须创建一个套接字连接。这个区域存在一个潜在问题,因为它不能保证各缓存之间的数据的一致性。但如果是按计划使用该区域,则不会出现这个问题。

远程区域

远程区域提供了一个使用远程方法调用(RMI)API 的缓存区域。这个区域使用一台远程服务器处理缓存数据。这台远程缓存服务器可以被多个 JCS 客户端应用程序用于存储缓存数据。一些侦听器被定义用于收集来自客户端和服务器的请求。这个缓存区域帮助减少串行化和多个连接点的开销。

回页首

JCS 配置

配置 JCS 就是简单地创建和填充一个 cache.ccf 文件。这个文件定义缓存应该使用哪些区域,以及这些区域的属性或选项。根据应用程序的需求配置这个文件是一种快速扩展缓存的简便方式。您可以指定许多适合配置的选项和属性来满足需求。

清单 1 显示的是最基本的 cache.ccf 文件 — 一个纯内存缓存配置:

清单 1. JCS 的基本配置
jcs.default=jcs.default.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes
jcs.default.cacheattributes.MaxObjects=1000
jcs.default.cacheattributes.MemoryCacheName=
org.apache.jcs.engine.memory.lru.LRUMemoryCache

从清单 1 中可以看出,该配置文件将内存缓存指定为一个 LRUMemoryCache。还可以看到,内存中能保存的对象的最大数量被设置为 1000

大多数应用程序的缓存系统配置要比清单 1 中复杂得多。在清单 2 的配置中,我在定义自己的区域(OUR_REGION)时使用了一个内存区域和一个磁盘区域:

清单 2. 在 JCS 配置中定义的区域
jcs.default=DISK_REGION
jcs.default.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes
jcs.default.cacheattributes.MaxObjects=1000
jcs.default.cacheattributes.MemoryCacheName=
org.apache.jcs.engine.memory.lru.LRUMemoryCache jcs.region.OUR_REGION=DISK_REGION
jcs.region.OUR_REGION.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes
jcs.region.OUR_REGION.cacheattributes.MaxObjects=1000
jcs.region.OUR_REGION.cacheattributes.MemoryCacheName=
org.apache.jcs.engine.memory.lru.LRUMemoryCache
jcs.region.OUR_REGION.cacheattributes.UseMemoryShrinker=true
jcs.region.OUR_REGION.cacheattributes.MaxMemoryIdleTimeSeconds=3600
jcs.region.OUR_REGION.cacheattributes.ShrinkerIntervalSeconds=60
jcs.region.OUR_REGION.cacheattributes.MaxSpoolPerRun=500
jcs.region.OUR_REGION.elementattributes=org.apache.jcs.engine.ElementAttributes
jcs.region.OUR_REGION.elementattributes.IsEternal=false jcs.auxiliary.DISK_REGION=org.apache.jcs.auxiliary.disk.indexed.IndexedDiskCacheFactory
jcs.auxiliary.DISK_REGION.attributes=
org.apache.jcs.auxiliary.disk.indexed.IndexedDiskCacheAttributes
jcs.auxiliary.DISK_REGION.attributes.DiskPath=c:/jcs/disk_region
jcs.auxiliary.DISK_REGION.attributes.maxKeySize=100000

JCS 辅助插件

除了 4 个核心缓存实现外,JCS 还提供了一些辅助插件,它们是区域可以使用的可选插件。这些辅助插件包括索引磁盘缓存(Indexed Disk Cache)、TCP 外围缓存(TCP Lateral Cache)和远程缓存服务器(Remote Cache Server)。例如,索引磁盘缓存允许在到达内存阈值时在磁盘上交换项目。这使得每个区域能更灵活地控制其缓存,提供一种类似于大多数操作系统所使用的虚拟内存的存储方法。cache.ccf
配置文件可以让每个辅助区域满足应用程序的需求。

清单 2 中的第一行表明该配置将默认区域设置为 DISK_REGIONDISK_REGION 是IndexedDiskCacheFactory 类型,并且该文件在磁盘上指定为
c:\jcs\disk_region。清单 2 中的第二个配置组定义了我自己的区域,我为它添加了一些选项,这种类型的配置(在指定用户定义区域时同时使用内存区域和磁盘区域)是很常见的。清单 2 中的第 3 个配置组定义了一个 辅助区域

JCS 有两个依赖项:concurrent 和 commons-logging(JCS
1.2.7.0 之前的版本中,还有两个其他依赖项:commons-collections 和 commons-lang)。

回页首

JCS 的基本用法

学习 JCS 基础知识的一个好方法是查看 API 最常用的方法。最好从初始化区域开始。初始化 JCS 缓存区域对象能使您访问大部分所需的常用方法。清单 3 初始化 JCS 对象并获得一个默认缓存区域实例:

清单 3. 检索默认缓存区域
// Initialize the JCS object and get an instance of the default cache region
JCS cache = JCS.getInstance("default");

检索 JCS 实例后,可以调用最需要的方法。put 方法将一个新对象放入缓存中。接下来只需一个 key(第一个参数)和一个 value(第二个参数)。清单
4 显示一个基本示例:

清单 4. 设置缓存项
// Set up
String key = "key0";
String value = "value0"; // Place a new object in the cache
cache.put(key, value);

清单 4 中的示例使用字符串值作为参数,但是您可以使用任何对象。

检索缓存对象只不过是使用 JCS 提供的 get 方法。清单
5 显示了一个简单示例。同样,本例使用了一个字符串参数,但您可以使用任何对象。

清单 5. 检索缓存项
// Retrieve a cached object
String cachedData = (String)cache.get(key);

测试缓存数据的有效性可能是处理缓存系统时需要使用的另一种方法。在 JCS 中,没有定义只测试缓存项是否存在的测试缓存方法。但是 get方法的返回值可以帮助您。清单
6 显示了一种获得此必要功能的方式:

清单 6. 测试缓存项的有效性
// Retrieve a cached object
String cachedData = (String)cache.get(key); // Check if the retrieval worked
if (cachedData != null) {
// The cachedData is valid and can be used
System.out.println("Valid cached Data: " + cachedData);
}

最后需要几个用于在使用 JCS、缓存项和缓存区域后清除它们的常用缓存实用程序。JCS 提供了一种 clear 方法,用于从调用的缓存区域中删除所有缓存数据。此外,还提供了一个 remove 方法,用于删除指定缓存项。dispose 方法也可以处理初始化的
JCS 区域。清单 7 显示了如何使用这些方法:

清单 7. 清除缓存区域
// Dispose of a specific cached item
cache.remove(key); // Dispose of all cache data
cache.clear(); // Dispose of the cache region
cache.dispose();

回页首

JCS 和 Java 对象

JCS 优于其他缓存系统(请参阅 参考资料)的一个地方是它可以很好地使用对象。大多数
Web 应用程序是使用面向对象的方法通过 Java 技术创建的。例如,与连续从数据库中逐段检索对象相比,缓存对象使应用程序能够更好地执行。

设计一个简单的面向对象的 JCS 站点的第一个步骤是创建需要存储的对象。在本例中,我将开发一个基本 blogging 站点。清单 8 显示了我将使用的 BlogObject 类:

清单 8. BlogObject 类
package com.ibm.developerWorks.objects;

import java.io.Serializable;
import java.util.Date; public class BlogObject implements Serializable {
private static final long serialVersionUID = 6392376146163510046L;
private int blogId;
private String author;
private Date date;
private String title;
private String content; public BlogObject(int blogId, String author, Date date, String title, String content) {
this.blogId = blogId;
this.author = author;
this.date = date;
this.title = title;
this.content = content;
} public int getBlogId() {
return this.blogId;
} public String getAuthor() {
return this.author;
} public Date getDate() {
return this.date;
} public String getTitle() {
return this.title;
} public String getContent() {
return this.content;
}
}

在一个类中表示对象后,接着还需要一个类来管理该对象。管理器处理所有与 blog 对象相关的管理和缓存功能。在本例中,管理器将处理三大任务:

  • 检索 blog 对象
  • 在缓存中设置 blog 对象
  • 从缓存中清除 blog 对象

如清单 9 所示,getBlog 方法检索
blog 对象。该方法首先试图从缓存获得 blog 对象。如果该对象不在缓存中,它将根据其他机制获取该对象:

清单 9. 通过 blog 管理器检索 blog 对象
public BlogObject getBlog(int id) {
BlogObject blog = null; try {
blogCache = JCS.getInstance(blogCacheRegion);
blog = (BlogObject)blogCache.get(id);
} catch (CacheException ce) {
blog = null;
} if (blog == null) {
blog = DatabaseManager.getBlog(id);
this.setBlog(
blog.getBlogId(),
blog.getAuthor(),
blog.getDate(),
blog.getTitle(),
blog.getContent()
);
} return blog;
}

在清单 9 中,我使用一个数据库作为检索 blog 对象的替代机制。根据另一种机制检索该对象时,应该将该对象设置为缓存,以便下一次检索可以直接从该缓存获取这个对象。

如清单 10 所示,setBlog 方法将
blog 对象放在缓存中。这个方法比较简单,因为它只是使用传入的信息创建一个新的 blog 对象,然后将这个对象放在缓存中。

清单 10. 通过 blog 管理器将 blog 对象放在缓存中
public boolean setBlog(int bId, String author, Date date, String title, String content) {
BlogObject blog = new BlogObject(bId, author, date, title, content); try {
blogCache = JCS.getInstance(blogCacheRegion);
blogCache.put(bId, blog);
return true;
} catch (CacheException ce) {
return false;
}
}

如清单 11 所示,cleanBlog 方法要么从缓存中清除一个指定的
blog,要么从缓存中清除掉所有 blog。这个方法使用 JCS 的 remove 和 clear方法来清除缓存对象。

清单 11. 通过 blog 管理器从缓存中删除 blog 对象
public boolean cleanBlog(int blogId) {
try {
blogCache = JCS.getInstance(blogCacheRegion);
blogCache.remove(blogId);
} catch (CacheException ce) {
return false;
}
return true;
} public boolean cleanBlog() {
try {
blogCache = JCS.getInstance(blogCacheRegion);
blogCache.clear();
} catch (CacheException ce) {
return false;
}
return true;
}

前面的几个类展示了使用 JCS 缓存对象是很简单的。拥有对象管理器并使用简单的对象表示之后,您就获得一种在 Web 应用程序中处理对象的简单但强大的方法。

回页首

缓存元数据

JCS 提供了更多方法,向应用程序添加缓存所用的方法只是其中的一小部分。例如,它提供了收集缓存对象和缓存区域元数据的实用程序。您可以轻松检索以下内容:

  • 缓存键名称
  • 创建缓存项的时间
  • 缓存可以存在的最长时间
  • 缓存过期时间

清单 12 中的例子显示如何检索缓存项的元数据:

清单 12. 检索缓存项的元数据
try {
JCSAdminBean admin = new JCSAdminBean();
LinkedList linkedList = admin.buildElementInfo(regionName);
ListIterator iterator = linkedList.listIterator(); while (iterator.hasNext()) {
CacheElementInfo info = (CacheElementInfo)iterator.next();
System.out.println("Key: " + info.getKey());
System.out.println("Creation Time: " + info.getCreateTime());
System.out.println("Maximum Life (seconds): " + info.getMaxLifeSeconds());
System.out.println("Expires in (seconds): " + info.getExpiresInSeconds());
}
} catch (Exception e) {
}

缓存项的元数据很有用,但获取各个缓存区域的元数据也很有帮助。这个信息让您知道缓存有多少数据,它们会进入哪个区域,包括缓存丢失、缓存提示和缓存更新。清单 13 中的示例显示如何获得此信息:

清单 13. 检索缓存区域的元数据
try {
JCSAdminBean admin = new JCSAdminBean();
LinkedList linkedList = admin.buildCacheInfo();
ListIterator iterator = linkedList.listIterator(); while (iterator.hasNext()) {
CacheRegionInfo info = (CacheRegionInfo)iterator.next();
CompositeCache compCache = info.getCache();
System.out.println("Cache Name: " + compCache.getCacheName());
System.out.println("Cache Type: " + compCache.getCacheType());
System.out.println("Cache Misses (not found): " + compCache.getMissCountNotFound());
System.out.println("Cache Misses (expired): " + compCache.getMissCountExpired());
System.out.println("Cache Hits (memory): " + compCache.getHitCountRam());
System.out.println("Cache Updates: " + compCache.getUpdateCount());
}
} catch (Exception e) {
}

收集缓存区域和项的元数据能帮助您分析 Web 站点的哪些区域和项目需要优化。元数据也能帮助您管理时间敏感型的缓存数据。例如,您可以使用每个缓存项的最长生命周期和过期时间来为需要更新数据的特定用户刷新缓存数据。

回页首

结束语

JCS 是为 Java 开发人员提供的功能强大但简单易用的缓存系统。它为桌面和类似的 Web 应用程序提供数据缓存。类似桌面的 Web 应用程序的发展前景是提高速度和敏捷性。缓存数据对这些方面非常有益。本文概述如何配置和使用 JCS。此外,还讨论了基本缓存方法所需要语法,以及如何在常见 Web 应用程序中缓存对象和检索缓存元数据。解了 JCS 的基本知识之后,您现在可以利用数据缓存功能来开发下一个 Web 站点了。您还可以学习其他几个提供高级功能的 JCS 区域,比如 HTTP Servlet 访问、JCS
实用程序、基本 HTTP 验证和其他辅助区域。

参考资料

学习

获得产品和技术

  • JCS:下载 JCS。
  • 下载 IBM 产品评估版,试用这些来自
    DB2、Lotus、Rational、Tivoli 和 WebSphere 的应用程序开发工具和中间件产品。

讨论

使用缓存构建更快的 Web 应用程序的更多相关文章

  1. 使用 jQuery UI 和 jQuery 插件构建更好的 Web 应用程序

    简介: 对于那些使用 JavaScript 和 jQuery 库从桌面应用程序转向 Web 应用程序的开发人员来说,他们还不习惯去考虑应用程序基本的外观,因为这些以前都是由操作系统来处理的.了解 jQ ...

  2. 构建 iOS 风格移动 Web 应用程序的8款开发框架

    使用 HTML5,CSS3 和 JavaScript 开发移动应用经过实践证明是一种可行的方式.这里收录了几款 iOS 风格的手机应用程序开发框架,帮助您使用擅长的 Web 技术来开发移动应用程序.这 ...

  3. 嵌入式服务器jetty,让你更快开发web

    概述 jetty是什么? jetty是轻量级的web服务器和servlet引擎. 它的最大特点是:可以很方便的作为嵌入式服务器. 它是eclipse的一个开源项目.不用怀疑,就是你常用的那个eclip ...

  4. 使用 Asp.net core 2.0 + Angular 4 构建车辆管理的Web应用程序

    https://www.codeproject.com/Articles/1210559/Asp-net-core-Angular-Build-from-scratch-a-web

  5. 响应式Web设计:构建令人赞叹的Web应用程序的秘诀

    骨架屏(Skeleton Screen) 参考博客:https://medium.com/@owencm/reactive-web-design-the-secret-to-building-web- ...

  6. 最好的10个移动 Web 应用程序开发框架

    在近期几年里,移动互联网快速发展.市场潜力巨大. 继计算机.互联网之后,移动互联网正掀起第三次信息技术革命的浪潮,新技术.新应用不断涌现.今天这篇文章向大家推荐10大优秀的移动Web开发框架.帮助开发 ...

  7. 精通Web Analytics 2.0 (9) 第七章:失败更快:爆发测试与实验的能量

    精通Web Analytics 2.0 : 用户中心科学与在线统计艺术 第七章:失败更快:爆发测试与实验的能量 欢迎来到实验和测试这个棒极了的世界! 如果Web拥有一个超越所有其他渠道的巨大优势,它就 ...

  8. Gradle更小、更快构建APP的奇淫技巧

    本文已获得原作者授权同意,翻译以及转载原文链接:Build your Android app Faster and Smaller than ever作者:Jirawatee译文链接:Gradle更小 ...

  9. 【转】UGUI研究院之缓存策略让UI打开更快(三十)

    UGUI研究院之缓存策略让UI打开更快(三十) [投稿]Unity3D游戏优化之头顶UI 注意里面提到了:SuperTextMesh:能渲染动态文字,富文本支持图文混排,缺点是支持atlas但很弱,资 ...

  10. [译] 优化 WEBPACK 以更快地构建 REACT

    原文地址:OPTIMIZING WEBPACK FOR FASTER REACT BUILDS 原文作者:Jonathan Rowny 译文出自:掘金翻译计划 本文永久链接:https://githu ...

随机推荐

  1. Kubernetes-9:Service介绍及演示

    Service Kubernetes 的Service定义了这样一种抽象:一个 Pod 的逻辑分组,一种可以访问他们的策略 -- 微服务,这一组Pod能够被Service访问到,通常是通过tabel ...

  2. PyTorch从入门到放弃之张量模块

    目录 张量的数据类型 torch.rand()函数 torch.randn()函数 torch.normal()函数 torch.linspace()函数 torch.manual_seed()函数 ...

  3. SpringBoot兼容SpringMVC带有.do后缀的请求

    背景 MVC框架请求的都是.do后缀,但controller控制层拦截的是没有后缀的链接.如controller请求/111/222,当请求/111/222.do时,可以正常进入.当我们将存量一些旧工 ...

  4. 给vue+element-ui动态设置主题色(包括外链样式、内联样式、行内样式)

    基本思路 实现思路:实现一个mixins混入的主题js即theme.js,注册到全局下.使用el-color-picker组件切换颜色的时候,把颜色值传递到根root下,在根实例下监听主题色的变化来更 ...

  5. 亮相CCIG2024,合合信息文档解析技术破解大模型语料“饥荒”难题

        近日,2024中国图象图形大会在古都西安盛大开幕.本届大会由中国图象图形学学会主办,空军军医大学.西安交通大学.西北工业大学承办,通过二十多场论坛.百余项成果,集中展示了生成式人工智能.大模型 ...

  6. Spring —— 注解开发(管理第三方bean)

    第三方bean管理       第三方bean依赖注入       

  7. mysql alter table修改表命令整理

    这篇文章主要介绍了mysql alter table修改表命令整理的相关资料,需要的朋友可以参考下   MYSQL ALTER TABLE命令用于修改表结构,例如添加/修改/删除字段.索引.主键等等, ...

  8. k8s的容器的webssh实现

    Vite2.x + Vue3.x + Xtermjs4 相关信息 编程语言:TypeScript 4.x + JavaScript 构建工具:Vite 2.x 前端框架:Vue 3.x 路由工具:Vu ...

  9. 系统 内核启动期间使用ftrace

    启动阶段使能event trace 同上,配置commandline: trace_event=sched:*,timer:*,irq:* trace_buf_size=40M 有上面的实例可以知道, ...

  10. 线段树介绍(segment tree)

    1.引入 给定一个区间\([1, n]\),希望你实现一种数据结构,支持以下操作: 1.修改\(i\)号节点的值. 2.询问区间\([i, j]\)中所有节点的和. 这不是树状数组板子 3.修改区间\ ...