资讯详情

apache common JCS的使用

前言

对于JCS研究仍然需要回到过去redis的场景。主要是redis大量数据可以作为分布式缓存集中在内存中。但是,过程和redis通信最终是过程之间的通信,所有数据都需要序列化和反序列化。在高频访问场景中,中间的费用实际上非常大。最简单的就是我在顶级的时候参加的性能测试。当时单压登录时,瓶颈就显示了redis反序列化过程更准确。 无论压力测试方法是否合理,这个瓶颈在很多情况下都不容忽视,比如会话验证。无论是否需要会话验证,每个接口都需要遵循相关的逻辑。如果逻辑中使用的某些配置值(例如不需要验证)uri有哪些)在redis其实这个费用挺大的,平时不显,压力大了就显了。当时我用了一个HashMap临时缓存。结果有两个问题:

  • 有内存泄漏
  • 缓存不能定期移除

事实上,我不知道过程中有缓存框架。这也是前段时间刚刚遇到的。最近忙了一段时间回来,发现还没整理好,就先用了。 当时选型还是选了很久,现在时间过得有点久了,细节记不清了。总之,我终于选择了JCS。当时仔细对比过Spring的cache机制,发现它不是缓存,而是一组方便我们进行缓存操作的类别spring和核心。我们暂时不在乎这里,先说吧。JCS怎么用吧。

Common JCS官网地址

目标

我对JCS定位是过程中的缓存,基本目标是将其纳入我未来建设项目的工具集中。这里有几个基本功能需要实现,即本研究的目标是:

  • 缓存数据的基本操作
  • 管理缓存池
  • 多过程之间的缓存同步

引入

官网的Getting Started中,使用jar引入包的形式jcs3.这不符合我常用的项目依赖管理模式。maven介绍方法如下:

        <dependency>             <groupId>org.apache.commons</groupId>             <artifactId>commons-jcs3-jcache</artifactId>             <version>3.0</version>         </dependency> 

核心概念

在使用jcs在此之前,我们应该首先了解它的一些核心概念,否则以后的许多配置和操作将无法讨论。

元素elements

元素,是jcs最小管理单元,即缓存数据对象。每个元素都可以独立设置。

区域regions

jcs使用该区域来管理元素分区。这样,我们就可以使用这种配置的一部分元素,而另一部分元素则使用另一种配置。

辅助功能auxiliaries

对于核心功能以外的扩展功能,如使用jdbc持久缓存、多过程同步等,详见官网相关章节。

配置

在官方网站的介绍中,我们需要配置根目录resource目录下创建一个cache.ccf文件用于配置缓存。即使这个文件什么都没有,缓存也可以使用。然而,当我使用缓存时,我可以控制它的记忆需求,我们仍然需要知道它是如何配置的。

总体配置规则

一般来说,缓存包括三种配置:

  • 默认及系统配置
  • 指定区域配置
  • 辅助缓存定义

以下是各部分配置结构的简配置结构,后面详细整理具体配置内容。

默认配置

在使用JCS使用任何未指定配置的区域default区域配置。以下是正确的default区域的一点样例配置。

jcs.default=DC,RFailover jcs.default.cacheattributes=org.apache.commons.jcs3.engine.CompositeCacheAttributes jcs.default.cacheattributes.MaxObjects=1000 

最重要的是jcs.default=DC,RFailover。这将告诉我们使用了什么辅助缓存。然而,这些辅助缓存将在后面独立定义。我们可以根据需要添加任何数量的辅助缓存,并用英文逗号将其分开。远程和水平辅助缓存可能会发生冲突,需要注意。

区域配置

以下是区域配置的示例

jcs.region.testCache=DC,RFailover jcs.region.testCache.cacheattributes= org.apache.commons.jcs3.engine.CompositeCacheAttributes jcs.region.testCache.cacheattributes.MaxObjects=1000 

我们注意到默认配置是基于jcs.default以上配置为开头jcs.region.testCache开头testCache该区域的配置default对应,jcs.region.testCache=DC,RFailover也是辅助缓存的配置。

辅助缓存配置

以下是两个辅助缓存配置的例子

jcs.auxiliary.DC=org.apache.commons.jcs3.auxiliary.disk.DiskCacheFactory jcs.auxiliary.DC.attributes=org.apache.commons.jcs3.auxiliary.disk.DiskCacheAttributes jcs.auxiliary.DC.attributes.DiskPath=c:/dev/cache/raf jcs.auxiliary.RFailover=org.apache.commons.jcs3.auxiliary.remote.RemoteCacheFactory jcs.auxiliary.RFailover.attributes=org.apache.commons.jcs3.auxiliary.remote.RemoteCacheAttributes jcs.auxiliary.RFailover.attributes.RemoteTypeName=LOCAL jcs.auxiliary.RFailover.attributes.FailoverServers=localhost:1102,localhost:1101 

以上定义了元素和区域配置中使用的两个辅助缓存。我们可以看到它们配置的开始是jcs.auxiliary.DCjcs.auxiliary.RFailover辅助缓存似乎主要用于远程同步和本地持久化。

具体配置参数

官方网站上只有配置参数的例子,没有详细的配置参数说明。然而,它所有的配置都是特定的类别,所以我们可以去类别查看具体的配置说明,以及可以配置的参数。

org.apache.commons.jcs3.engine.CompositeCacheAttributes

在default中的jcs.default.cacheattributes属性使用此类配置。该类别定义了缓存区域的默认配置。如果根本没有在配置文件中进行配置,则该类别中的硬编码将用于配置缓存区域。属性不是特别多。让我列出它:

  • useLateral:默认值true。横向缓存是否允许
  • useRemote:默认值true。是否允许远程缓存
  • useMemoryShrinker:默认值false。内存收缩线程是否运行
  • maxObjs:默认值100。允许同时存在的最大缓存对象。需要注意的是,这里必须限制最大数量。
  • maxMemoryIdleTimeSeconds:默认值60*120.默认缓存最大闲置秒。该配置仅在启用收缩后有效,如果闲置超时,将收缩并储存在磁盘上。
  • shrinkerIntervalSeconds:默认值30。默认收缩间隔秒数
  • maxSpoolPerRun:默认值2。每轮存储到磁盘的内存块数。
  • cacheName:区域名称,无默认值
  • memoryCacheName:实现缓存类名称,无默认值
  • diskUsagePattern:默认情况下,磁盘使用模式DiskUsagePattern.SWAP
  • spoolChunkSize:默认值-1。存储在磁盘中的最大轮数。

org.apache.commons.jcs3.engine.ElementAtributes

元素配置

  • IS_SPOOL:默认值true。该元素是否可以被存储到磁盘
  • IS_LATERAL:默认值true。该元素是否可被横向扩展。
  • IS_REMOTE:默认值true。该元素是否可以被发送到远程缓存
  • IS_ETERNAL:默认值true。该元素是否永恒。该配置为true时,可以绕开最大生命周期和最大闲置时间的限制。
  • maxLife:默认值-1。最大生命时长(秒数),-1为永不过期。
  • maxIdleTime:默认值-1。入口(entry)可以被最大闲置的时间。
  • size:缓存的字节数,默认为0,必须被手动设置。
  • createTime:创建时间,用来控制最大生命时长的。
  • lastAccessTime:最后一次访问时间,用来控制最大闲置时间的

使用

首先获取cache对象

CacheAccess<String, String> cache = JCS.getInstance( "default" );

泛型里指定的就是缓存的key和value的类型。getInstance中传入的是region的名称,没有配置的名称也是可以传的,会按照默认配置返回。接下来我们就可以拿着这个对象对缓存进行操作了。

下面是一段典型的对缓存赋值的操作。

try
{
    cache.put(key,value);
}
catch ( CacheException e )
{
    logger.error(String.format( "Problem putting value %s in the cache, for key %s%n%s",
            value, key, e.getMessage() ) );
    throw e;
}

可以看到,操作异常是可以使用缓存捕捉的。 常用的操作也就put,get和remove,具体就不详细说明了,很简单。 这样日常使用也就够了。

一些进阶的使用

上面的操作,作为使用缓存进行增删改查已经没有什么问题了。但是,我们有些时候可能会需要使用缓存做一些进阶的事情,就需要对其进行更加深入的控制和监听了。

订阅事件

可用事件

在jcs3中,可以订阅缓存元素的一些事件,方便我们在元素相关的生命周期,或者发生相应的事情时获得通知,及时处理。

  • ELEMENT_EVENT_EXCEEDED_MAXLIFE_BACKGROUND:该元件超过了其最大寿命。这是在后台清理中检测到的。 ELEMENT_EVENT_EXCEEDED_MAXLIFE_ONREQUEST:该元件超过了其最大寿命。这是根据请求检测到的。 ELEMENT_EVENT_EXCEEDED_IDLETIME_BACKGROUND:元素已超出其最大空闲状态。这是在后台清理中检测到的。 ELEMENT_EVENT_EXCEEDED_IDLETIME_ONREQUEST:元素已超出其最大空闲时间。这是根据请求检测到的。 ELEMENT_EVENT_SPOOLED_DISK_AVAILABLE:该元素已推出内存存储区,有一个磁盘存储可用于该区域,并且该元素被标记为可假脱机。 ELEMENT_EVENT_SPOOLED_DISK_NOT_AVAILABLE:该元素已推出内存存储区,并且没有可用于该区域的磁盘存储区。 ELEMENT_EVENT_SPOOLED_NOT_ALLOWED:该元素已推出内存存储区,该区域有一个磁盘存储区可用,但该元素被标记为不可假脱机。

编码调用

具体的事件处理需要实现接口:org.apache.commons.jcs3.engine.control.event.behavior.IElementEventHandler 事件处理的实例可以直接添加到元素里,也可以放到区域的默认配置里,但是好像只能通过代码进行添加。以下是官网的一些样例代码,由于我这里还没有实际的业务点使用,就没有对其进行测试了。记录在这里,以后就不用老去翻官网了。 通过元素添加

CacheAccess<String, String> jcs = JCS.getInstance( "myregion" );

. . .

MyEventHandler meh = new MyEventHandler();

// jcs.getDefaultElementAttributes returns a copy not a reference
IElementAttributes attributes = jcs.getDefaultElementAttributes();
attributes.addElementEventHandler( meh );
jcs.put( "key", "data", attributes );

通过区域的默认配置进行设置

CacheAccess<String, String> jcs = JCS.getInstance( "myregion" );

. . .

MyEventHandler meh = new MyEventHandler();

// this should add the event handler to all items as
//they are created.
// jcs.getDefaultElementAttributes returns a copy not a reference
IElementAttributes attributes = jcs.getDefaultElementAttributes();
attributes.addElementEventHandler( meh );
jcs.setDefaultElementAttributes( attributes );

多进程同步

在我的实际使用场景中,我希望将数据字典以及一些常用的配置放到缓存里,在使用的时候直接通过缓存加载而不是联表查询,以降低表之间的耦合,减少sql所承载的职责。但是,数据字典中数据的维护是在后台的,使用的时候大多实在业务进程,它们一般是以springboot服务的形式承载的。所以,我们就需要后台服务进程可以更新业务进程的缓存。 在jcs3中,有三种方式可以解决这个问题:

  • remote cache:远程缓存。其实际的模型是缓存的Server/Client模型这个东西。也就是,缓存只有一份,客户端都去服务端去读取缓存。换句话说,在这中间还是存在远程传输和序列化反序列化的开销的。
  • JGroup:在官方文档中说jcs支持这种方式对缓存进行扩展,但是它的速度比TCP横向扩展要慢很多,并不推荐使用。
  • 横向扩展:横向扩展是通过TCP建立通道,维护不同进程中的缓存更新。相互之间的发现方式有TCP和UDP。我比较倾向于使用这种方式。

由于这部分涉及一些具体业务和两个项目,等我写好了之后以新的贴子进行更新吧。本文就到这里了。

标签: jcs油压继电器参数

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台