热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

OpenFire源码学习之九:OF的缓存机制

关于缓存,openfire存储到了本地JVM中。本人认为这样并不是很好。以后会讲一篇Redis的缓存。实际应用中,本人讲openfire诸多缓存内容放置了redis中。这里就看看openfi

关于缓存,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

Mapcaches = new ConcurrentHashMap();

//存储所有创建的Cache名称

MapcacheNames = new HashMap();

//存储Cache的属性

MapcacheProps = new HashMap();

缓存配置文件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里面的一些缓存类。当然还有关于消息缓存比较重要的。比如用户消息存储大小的几种策略:存储消息超过了大小,就讲消息反弹,或者丢弃这样的策略。

本人认为这种策略并不是很好。后面会些一些关于消息优化策略等文章,希望你来阅读。




推荐阅读
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • 本文介绍了在Android开发中使用软引用和弱引用的应用。如果一个对象只具有软引用,那么只有在内存不够的情况下才会被回收,可以用来实现内存敏感的高速缓存;而如果一个对象只具有弱引用,不管内存是否足够,都会被垃圾回收器回收。软引用和弱引用还可以与引用队列联合使用,当被引用的对象被回收时,会将引用加入到关联的引用队列中。软引用和弱引用的根本区别在于生命周期的长短,弱引用的对象可能随时被回收,而软引用的对象只有在内存不够时才会被回收。 ... [详细]
  • 解决Sharepoint 2013运行状况分析出现的“一个或多个服务器未响应”问题的方法
    本文介绍了解决Sharepoint 2013运行状况分析中出现的“一个或多个服务器未响应”问题的方法。对于有高要求的客户来说,系统检测问题的存在是不可接受的。文章详细描述了解决该问题的步骤,包括删除服务器、处理分布式缓存留下的记录以及使用代码等方法。同时还提供了相关关键词和错误提示信息,以帮助读者更好地理解和解决该问题。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 本文介绍了如何使用C#制作Java+Mysql+Tomcat环境安装程序,实现一键式安装。通过将JDK、Mysql、Tomcat三者制作成一个安装包,解决了客户在安装软件时的复杂配置和繁琐问题,便于管理软件版本和系统集成。具体步骤包括配置JDK环境变量和安装Mysql服务,其中使用了MySQL Server 5.5社区版和my.ini文件。安装方法为通过命令行将目录转到mysql的bin目录下,执行mysqld --install MySQL5命令。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • 纠正网上的错误:自定义一个类叫java.lang.System/String的方法
    本文纠正了网上关于自定义一个类叫java.lang.System/String的错误答案,并详细解释了为什么这种方法是错误的。作者指出,虽然双亲委托机制确实可以阻止自定义的System类被加载,但通过自定义一个特殊的类加载器,可以绕过双亲委托机制,达到自定义System类的目的。作者呼吁读者对网上的内容持怀疑态度,并带着问题来阅读文章。 ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
author-avatar
ze602
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有