Openfire 的 Cache机制

Openfire 中多处用到了Cache 来存储那些访问较为频繁的数据,例如userManager中的userCache,rosterManager 中的rosterCache。

以下为Openfire中Cache的实现机制:

1. Cache 接口:

interface Cache<K,V> extends java.util.Map<K,V>

提供了基本的Cache接口方法。

2. Cacheable 接口:

interface Cacheable extends java.io.Serializable

继承了序列化接口,如果是自己定义的数据需要存储在Cache中,则需要实现此接口中的getCacheSize()方法,否则会在Cache.put 时报如下的错误:

java.io.NotSerializableException: 
	at java.io.ObjectOutputStream.writeObject0(Unknown Source)
	at java.io.ObjectOutputStream.writeObject(Unknown Source)
	at org.jivesoftware.util.cache.DefaultCache.calculateSize(DefaultCache.java:583)
	at org.jivesoftware.util.cache.DefaultCache.put(DefaultCache.java:141)
	at org.jivesoftware.util.cache.CacheWrapper.put(CacheWrapper.java:129)

3.CacheSizes:

一个提供计算对象大小的类。比较好用的是sizeOfMap()、sizeOfCollection()、sizeOfString() 方法,可在实现getCacheSize() 方法时直接调用。

4.DefaultCache:

Openfire中Cache接口的一个实现,其中保持了两个链表lastAccessedList (用于被访问的顺序管理),ageList (用于生命周期的管理)。

主要提供了以下方法:

put()     存储一个指定键值对。计算数据的大小,超过Cache设置的最大size 90% 的数据将直接被丢掉;并将添加的数据加入到两个链表中,并对Cache进行一次整理。
get()     根据Key查找一个数据。会先清除那些过期的数据,更新命中和 miss 的次数,并在查找到时将此数据从lastAccessedList 中移动到链表的头部。
remove()  从Cache中移除一个键值对。更新Cache大小,并从链表中移除对应的数据。
clear()   清空整个Cache。包括链表,各个统计的值的大小。
size()    获取Cache中数据个数。会先清理过期的数据。
isEmpty() 判断是否为空。会先清理过期的数据。 
values()  获取所有数据,返回一个Collection。会先清理过期的数据。
containsKey()  判断是否含有指定键。会先清理过期的数据。
putAll()       将一个map中的所有数据存储到Cache中。
containsValue()     判断是否含有指定值。会先清理过期的数据。
containsNullValue()  是否含有空值。
entrySet()          返回一个含有所有数据的Set。
keySet()            返回一个含有所有Key的Set。
getName/setName()   设置获取名称。
getCacheHits()      获取命中的次数。
getCacheMisses()    获取miss 的次数。
getCacheSize()      获取当前Cache的大小。
getMaxCacheSize/setMaxCacheSize()  设置获取Cache 的最大空间。
getMaxLifetime/setMaxLifetime()  设置获取 Cache 数据的最大生命周期。
calculateSize()         计算指定数据的大小。
注:这里可以看出所有要存储在Cache中的数据必须是Cacheable 或基础数据类型的,如果不是这两种,则需要能够序列化以便衡量数据的大小。

deleteExpiredEntries() 清除过期的数据。针对ageList链表中的节点进行判断。
cullCache()    在Cache太满的情况下清除一些数据,释放空间。


4.CacheFactoryStrategy 接口和 DefaultLocalCacheStrategy类:

CacheFactoryStrategy 接口主要定义了在集群模式下的Cache 管理方法。

DefaultLocalCacheStrategy 则为Openfire中使用的Cache 管理方法,并没有实现集群功能。

最主要的方法可以看下createCache()。

5.CacheFactory 工厂类:

这里用到了java 设计模式中的工厂模式

在Openfire 甚至我们自己写的插件中会用到各种各样的Cache,CacheFactory则提供了一个统一的创建和使用Cache的平台。

这里重点看三个成员:

Map<String,Cache> caches = new ConcurrentHashMap<String,Cache>();


Map<String,String> cacheNames = new HashMap<String,String>();


Map<String,Long> cacheProps = new HashMap<String,Long>();
第一个用来存储所有创建的Cache

第二个用来存储所有创建的Cache名称

第三个用来存储Cache的属性

整个Factory 中的大部分方法都是围绕这三个成员进行操作的。集群部分由于在strategy中未实现,暂不讨论。

createCache方法直接调用strategy 的createCache() 来创建Cache。

6.Cache的使用:

如果我们需要在使用Cache来实现某些数据的缓存,则可以使用Openfire的Cache机制,在CacheFactory的 static{} 代码块中添加我们自己的 Cache。在需要的地方使用createCache(),需要注意的是对Cache的操作需要考虑线程的同步和互斥。

PS: 在java  编程中使用此Cache 机制也是很不错的选择,对代码稍加修改就可到处使用。大笑

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值