(转)OpenFire源码学习之九:OF的缓存机制
转:http://blog.csdn.net/huwenfeng_2011/article/details/43415023
关于缓存,openfire存储到了本地JVM中。本人认为这样并不是很好。以后会讲一篇Redis的缓存。
实际应用中,本人讲openfire诸多缓存内容放置了redis中。这里就看看openfire自己的缓存吧。
Cache接口
类图:
Cache接口继承了Map工具类,它存储相关的对象在内存中独特的键、值队,可快速访问。所有的键和值添加到缓存必须实现Serializable接口。值可能实现缓存的接口,它允许缓存来确定对象的大小要快得多。这些限制允许缓存永远生长大于一个指定的字节数,并可选地分布到一个服务器集群。如果缓存的对象比较大的话,那么这样的对象将内剔除。当一个最大生命周期可以指定所有对象。在这种情况下,对象将被从缓存之后的时间删除,即使他们是经常访问的。这个特性很有用如果对象放入缓存表示数据,应该定期刷新,例如,访问一个数据库的时候。这里所有缓存操作是线程安全的。
基本缓存方法列表:
getMaxCacheSize()/setMaxCacheSize() |
返回以字节缓存的最大大小。如果缓存生命周期大于最大的值,那么最经常使用缓存项目将被删除。如果最大的缓存大小设置为-1,那它没有大小限制。 |
getMaxLifetime()/setMaxLifetime() |
返回最大的毫秒数,任何对象都可以放进缓存。一旦超过指定的毫秒数,对象将自动从缓存消除掉。如果最大的生命周期被设置为-1,那么对象永远不会过期。 |
getCacheSize()/setCacheSize() |
返回缓存的大小字节的内容。返回缓存的大小字节的内容。当这个值只是粗略的接近的时候,实际VM内存使用的缓存可以明显高于这个值报告的时候用这个放这个方法。 |
getCacheHits() |
返回的缓存命中率的数量。一个缓存命中时每次调用这个方法来缓存包含所请求的对象。跟踪缓存命中和未命中让一个衡量高效缓存,命中率越高,效率越高。 |
GetCacheMisses() |
返回的缓存未命中的数量。一个缓存命中时每次调用这个方法来缓存包含所请求的对象。跟踪缓存命中和未命中让一个衡量高效缓存,命中率越高,效率越高。 |
DefaultCache
它是Cache接口的一个实现,其中保持了两个链表(LinkedList)lastAccessedList (用于被访问的顺序管理),ageList(用于生命周期的管理)。缓存的算法如下:一个HashMap维持快速的对象查找。两个链表维护:保持对象的顺序从缓存访问,其他保持对象的顺序把它们添加到缓存原本。当对象被添加到缓存中,他们是第一个用一个CacheObject维护以下信息:
l 对象的大小(以字节为单位)。
l 一个指向该节点的链表,维护秩序的对象访问。保持一个参考节点让我们避免线性扫描的链表。
l 一个指向该节点的链表,维护对象在缓存的寿命。保持一个参考节点让我们避免线性扫描的链表。
从缓存中获取一个对象,一个散列查找时得到一个引用,它封装了正在寻找的实际对象CacheObject。对象是后来移动到前面的访问链表和任何必要的缓存清理完成。缓存删除和过期是根据需要执行。
该类主要提供了以下方法:
l put() 存储一个指定键值对。计算数据的大小,超过Cache设置的最大size 90% 的数据
将直 接被丢掉;并将添加的数据加入到两个链表中,并对Cache进行一次整理。
l get() 根据Key查找一个数据。会先清除那些过期的数据,更新命中和 miss 的次数,
并在查找到时将此数据从lastAccessedList 中移动到链表的头部。
l remove() 从Cache中移除一个键值对。更新Cache大小,并从链表中移除对应的数据。
l clear() 清空整个Cache。包括链表,各个统计的值的大小。
l size() 获取Cache中数据个数。会先清理过期的数据。
l isEmpty() 判断是否为空。会先清理过期的数据。
l values() 获取所有数据,返回一个Collection。会先清理过期的数据。
l containsKey() 判断是否含有指定键。会先清理过期的数据。
l putAll() 将一个map中的所有数据存储到Cache中。
l containsValue() 判断是否含有指定值。会先清理过期的数据。
l containsNullValue() 是否含有空值。
l entrySet() 返回一个含有所有数据的Set。
l keySet() 返回一个含有所有Key的Set。
l getName/setName() 设置获取名称。
l getCacheHits() 获取命中的次数。
l getCacheMisses() 获取miss 的次数。
l getCacheSize() 获取当前Cache的大小。
l getMaxCacheSize/setMaxCacheSize() 设置获取Cache 的最大空间。
l getMaxLifetime/setMaxLifetime() 设置获取 Cache 数据的最大生命周期。
l calculateSize() 计算指定数据的大小。
注:这里可以看出所有要存储在Cache中的数据必须是
Cacheable 或基础数据类型的,如果不是这两种,则需要能够
序列化以便衡量数据的大小。
l deleteExpiredEntries() 清除过期的数据。针对ageList链表中的节点进行判断。
l cullCache() 在Cache太满的情况下清除一些数据,释放空间。
Cacheable接口
Cacheable接口继承了序列化接口,如果是自己定义的数据需要存储在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)
Cacheable接口为对象添加到缓存定义了必要的行为。对象只需要知道他们是多大(以字节为单位),大小应该被认为是一个最佳的估计占多少内存对象,可能是基于实证试验或动态计算。计算的精确度大小非常的重要,应该尽量的减少计算的时间,这样缓存的操作会得到提升。
CacheSizes
一个提供计算对象大小的类,当您的类需要实现缓存的接口应该使用这个类来确定它们的大小。它包括Java的任何数据类型。如:
sizeOfObject()、sizeOfString()、sizeOfInt()、sizeOfChar()、
sizeOfBoolean()、sizeOfLong()、sizeOfDouble()、sizeOfDate()、
sizeOfMap()......
CacheFactory
CacheFactory提供了一个统一的创建和使用Cache的平台
//存储所有创建的Cache
Map<String,Cache>caches = new ConcurrentHashMap<String,Cache>();
//存储所有创建的Cache名称
Map<String,String>cacheNames = new HashMap<String,String>();
//存储Cache的属性
Map<String,Long>cacheProps = new HashMap<String,Long>();
缓存配置文件coherence-cache-config.xml
如果我们需要在使用Cache来实现某些数据的缓存,则可以使用Openfire的Cache机制,在CacheFactory的 static{} 代码块中添加我们自己的 Cache。在需要的地方使用createCache(),需要注意的是对Cache的操作需要考虑线程的同步和互斥。
- static {
- localCacheFactoryClass =
- JiveGlobals.getProperty(LOCAL_CACHE_PROPERTY_NAME,
- "org.jivesoftware.util.cache.DefaultLocalCacheStrategy");
- clusteredCacheFactoryClass =
- JiveGlobals.getProperty(CLUSTERED_CACHE_PROPERTY_NAME,
- "com.jivesoftware.util.cache.ClusteredCacheFactory");
- cacheNames.put("Favicon Hits", "faviconHits");
- cacheNames.put("Favicon Misses", "faviconMisses");
- cacheNames.put("Group", "group");
- 。。。。。。
- cacheProps.put("cache.publishedItems.size", 1024l * 1024 * 10);
- cacheProps.put("cache.publishedItems.maxLifetime", JiveConstants.MINUTE * 15);
这里主要是讲了openfire里面的一些缓存类。当然还有关于消息缓存比较重要的。比如用户消息存储大小的几种策略:存储消息超过了大小,就讲消息反弹,或者丢弃这样的策略。
本人认为这种策略并不是很好。后面会些一些关于消息优化策略等文章,希望你来阅读。
(转)OpenFire源码学习之九:OF的缓存机制的更多相关文章
- Volley源码解析(三) 有缓存机制的情况走缓存请求的源码分析
Volley源码解析(三) 有缓存机制的情况走缓存请求的源码分析 Volley之所以高效好用,一个在于请求重试策略,一个就在于请求结果缓存. 通过上一篇文章http://www.cnblogs.com ...
- (转)OpenFire源码学习之七:组(用户群)与花名册(用户好友)
转:http://blog.csdn.net/huwenfeng_2011/article/details/43413651 Group 在openfire中的gorop——组,也可以理解为共享组.什 ...
- (转)OpenFire源码学习之二十七:Smack源码解析
转:http://blog.csdn.net/huwenfeng_2011/article/details/43484199 Smack Smack是一个用于和XMPP服务器通信的类库,由此可以实现即 ...
- (转)OpenFire源码学习之十八:IOS离线推送
转:http://blog.csdn.net/huwenfeng_2011/article/details/43458213 IOS离线推送 场景: 如果您有iOS端的APP,在会话聊天的时候,用户登 ...
- (转)OpenFire源码学习之十:连接管理(上)
转:http://blog.csdn.net/huwenfeng_2011/article/details/43415827 关于连接管理分为上下两部分 连接管理 在大并发环境下,连接资源 需要随着用 ...
- (转)OpenFire源码学习之六:用户注册
转:http://blog.csdn.net/huwenfeng_2011/article/details/43413509 用户注册 注册流程: 1.客户端进行握手给服务端发送连接消息: <s ...
- (转)OpenFire源码学习之四:openfire的启动流程
转:http://blog.csdn.net/huwenfeng_2011/article/details/43413233 openfire启动 ServerStarter 启动流程图: 启动的总入 ...
- (转)即时通讯IM OpenFire源码学习之三:在Eclipse中构建源码
转:http://blog.csdn.net/huwenfeng_2011/article/details/43412617 源码搭建 下载地址: 地址:http://www.igniterealti ...
- yii2源码学习笔记(九)
Application是所有应用程序类的基类,接下来了解一下它的源码.yii2\base\Application.php. <?php /** * @link http://www.yiifra ...
随机推荐
- [CSP-S模拟测试]:字符(模拟+剪枝)
题目传送门(内部题33) 输入格式 第一行,两个整数$T,C$,表示测试数据组数和字符种类数.对于每组数据:第一行,一个正整数$M$:接下来的$M$行,每行两个整数$P_k,X_k$($S$的下标从$ ...
- 浅析DirectX11技术带给图形业界的改变(一) 浅析DirectX11技术带给图形业界的改变【转】
浅析DirectX11技术带给图形业界的改变(一) 浅析DirectX11技术带给图形业界的改变 前言:2009年10月23日,微软高调发布了其最新一代操作系统——Windows7,这款操作系统相对于 ...
- C++11中vector的几种遍历方法
假设有这样的一个vector: vector<int> line={1,2,3,4,5,6,7,8,9}; 需要输出vector里的每个元素,主函数如下: void showvec(con ...
- [STemWin教程入门篇]第二期:emWin5.xx的详细移植步骤
转自:http://bbs.armfly.com/read.php?tid=1545 重要说明:(0)由于这个移植教程是去年过年的时候做的,用的是5.16,这就不再做个5.20的移植了,方法是一样的. ...
- Objective-C UIWebview JS 交互
一.在OC中调用网页中的 js 方法. Objective-C 代码 [self.webView stringByEvaluatingJavaScriptFromString:@"alert ...
- Java第四次作业—面向对象高级特性(继承和多态)
Java第四次作业-面向对象高级特性(继承和多态) (一)学习总结 1.学习使用思维导图对Java面向对象编程的知识点(封装.继承和多态)进行总结. 2.阅读下面程序,分析是否能编译通过?如果不能,说 ...
- 记录以下mysql5.7在win使用Navicat无法链接的问题
1.前提 系统:win1o0 局域网服务器:ubuntu18.04 mysql版本:5.7 问题描述: 在ubuntu18.04下的shell 中使用mysql -uroot -p 是可以登陆的, ...
- UVA1632_Alibaba
题目链接 大致题意:直线上面有n个点,第i个点坐标为xi,它会在di时间消失,你可以选择从任何位置出发,求访问完所有点的最短时间,无解输出no solution 思路:这有一个难点就是,不知道状态该怎 ...
- angularJS CDN
http://cdn.static.runoob.com/libs/angular.js/1.4.6/angular.min.js
- Promise篇
Promise 原理解析与实现(遵循Promise/A+规范) 1 什么是Promise? Promise是JS异步编程中的重要概念,异步抽象处理对象,是目前比较流行Javascript异步编程解 ...