首先我们通过下图 了解到memcache在系统中处于大概什么的位置
然后我们了解下Memcached简介
1.1. 什么是Memcached? Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。
它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提供动态、数据库驱动网站的速度。class="Apple-converted-space">?
Memcached基于一个存储键/值对的HashMap,它并不提供冗余(复制其HashMap条目),当某个服务器停止运行或崩溃了,所有存放在服务器上的键/值对都将丢失。
但目前Memcached的客户端和代理程序可以提供多服务器的并联方式,可以提供一定的处理能力。
1.2. Memcached与其他分布式缓存的区别? Memcached与其它常用的分布式缓存(例如EhCache、OSCache、JBoss Cache)最主要的区别在于Memcached采用集中式缓存方式(即一台或多台缓存服务器为所有应用系统提供缓存能力),自身不提供集群能力,不提供缓存复制功能;而其他分布式缓存系统采用分布式缓存方式,各个应用系统内部提供数据缓存的能力,
多个缓存间采用组播或点对点的方式进行缓存同步。?
在性能上来看,Memcached比其它分布式缓存系统低一半以上(未考虑大量数据在其它缓存系统进行复制的影响);但从管理方面来看,Memcached的缓存采用集中管理的模式,应用系统可以水平扩展,
而其它分布式缓存在水平扩展的同时,必须同时调整缓存复制策略,一旦应用服务器节点大量扩展,对于缓存服务器间的数据复制将成几何数增加。
然后我们从官网http://memcached.org/下载 适合自身系统的memcache安装包
下载好之后解压
因为我是windows 操作
所以解压后 直接CMD到改目录
到memcached根目录?
1、安装?
memcached.exe –d install??
2、启动?
memcached.exe -d start?
现在来试试是否可以连接:?
使用方法为“telnet ip 端口号”,登录后使用“stats”命令?
cmd下?
telnet 192.168.1.135 11211(注意:这里只能用IP 不能用 localhost 或127.0.0.1? 11211端口默认的)?
然后使用:stats命令可以看到memcached的使用情况如下:?
time: 1255537291 服务器当前的unix时间戳?
total_items: 54 从服务器启动以后存储的items总数量?
connection_structures: 19 服务器分配的连接构造数?
version: 1.2.6 memcache版本?
limit_maxbytes: 67108864 分配给memcache的内存大小(字节)?
cmd_get: 1645 get命令(获取)总请求次数?
evictions: 0 为获取空闲内存而删除的items数(分配给memcache的空间用满后需?要删除旧的items来得到空间分配给新的items)?
total_connections: 19 从服务器启动以后曾经打开过的连接数?
bytes: 248723 当前服务器存储items占用的字节数?
threads: 1 当前线程数?
get_misses: 82 总未命中次数?
pointer_size: 32 当前操作系统的指针大小(32位系统一般是32bit)?
bytes_read: 490982 总读取字节数(请求字节数)?
uptime: 161 服务器已经运行的秒数
curr_connections: 18 当前打开着的连接数?
pid: 2816 memcache服务器的进程ID?
bytes_written: 16517259 总发送字节数(结果字节数)
get_hits: 1563 总命中次数?
cmd_set: 54 set命令(保存)总请求次数?
curr_items: 28 服务器当前存储的items数量
?
3.一些常用命令
-p 监听的端口
-l 连接的IP地址, 默认是本机
-d start 启动memcached服务
-d restart 重起memcached服务
-d stop|shutdown 关闭正在运行的memcached服务
-d install 安装memcached服务
-d uninstall 卸载memcached服务
-u 以的身份运行 (仅在以root运行的时候有效)
-m 最大内存使用,单位MB。默认64MB
-M 内存耗尽时返回错误,而不是删除项
-c 最大同时连接数,默认是1024
-f 块大小增长因子,默认是1.25
-n 最小分配空间,key+value+flags默认是48
-h 显示帮助
?
到此整个的memcache安装结束
?
那么该怎么样集成到EJB呢?
客户端调用有两种
一种是java_memcached-release_2.6.3依赖于此包
二种是alisoft-xplatform-asf-cache-2.5.1依赖于此包
我选择的是第二种原因是阿里软件的架构师岑文初进行封装的。里面的注释都是中文的,比较好详情http://www.infoq.com/cn/articles/memcached-java
重点我就讲这种结合EJB的使用
首先对xxxEJB引入alisoft-xplatform-asf-cache-2.5.1.jar
然后配置memcache.xml文件 记住一定要放在classpath下否则找不到
<memcached>
??? <!--memcached Client的配置,也就是一个IMemcachedCache的配置。Name必须填,表示Cache的名称,socketpool必须填,
??? 表示使用的远程通信连接池是哪一个,参看后面对于socketpool的定义。后面都是可选的,第三个参数表示传输的时候是否压缩,第四个参数表示默认的编码方式 -->
?<client name="mclient1" socketpool="pool1" compressEnable="true" defaultEncoding="UTF-8" >
??????? <!--errorHandler></errorHandler可定义错误处理类,一般不需要定义 -->
??? </client>
??? <client name="mclient2" socketpool="pool2" compressEnable="true" defaultEncoding="UTF-8" >
??? </client>??
???? <!--socketpool是通信连接池定义,每一个memcached Client要和服务端交互都必须有通信连接池作为底层数据通信的支持,name必填,表示名字,
???? 同时也是memcached client指定socketpool的依据,failover表示对于服务器出现问题时的自动修复。
???? initConn初始的时候连接数,minConn表示最小闲置连接数,maxConn最大连接数,maintSleep表示是否需要延时结束(最好设置为0,如果设置延时的话那么就不能够立刻回收所有的资源,
???? 如果此时从新启动同样的资源分配,就会出现问题),nagle是TCP对于socket创建的算法,socketTO是socket连接超时时间,aliveCheck表示心跳检查,确定服务器的状态。
???? Servers是memcached服务端开的地址和ip列表字符串,weights是上面服务器的权重,必须数量一致,否则权重无效? -->
??? <socketpool name="pool1" failover="true" initConn="10" minConn="5" maxConn="250" maintSleep="0"
??????? nagle="false" socketTO="3000" aliveCheck="true">
??????? <servers>192.168.1.137:11211</servers>
??????? <weights>5</weights>
??? </socketpool>??
??? <socketpool name="pool2" failover="true" initConn="10" minConn="5" maxConn="250" maintSleep="0"
??????? nagle="false" socketTO="3000" aliveCheck="true">
??????? <servers>192.168.0.53:11211</servers>
??????? <weights>5</weights>
??? </socketpool>
???? <!--虚拟集群设置,这里将几个client的cache设置为一个虚拟集群,当对这些IMemcachedCache作集群操作的时候,就会自动地对集群中所有的Cache作插入,寻找以及删除的操作,做一个虚拟交互备份? -->
??? <cluster name="cluster1">
??????? <memCachedClients>mclient1,mclient2</memCachedClients>
??? </cluster>????????????
</memcached>
然后创建一个类进行对象初始化
?//缓存管理器变量??
??? private ICacheManager manager;??
??? //缓存变量??
??? private IMemcachedCache cache;??
??????
??? //缓存名称??
??? /********************************单例模式(饿汉式)? begin***********************************************/??
??????
??? private? static CacheHandler cacheHandler=new CacheHandler();??
??? /**?
???? * 私有构造函数?
???? */??
??? private CacheHandler(){??
??????? System.out.println("---------------创建单例 begin--------------");??
??????? initCache();??
??????? System.out.println("---------------创建单例 end--------------");??
??? }??
??? public static CacheHandler getInstance(){??
??????? return cacheHandler;??
??? }??
??? /********************************单例模式(饿汉式)? end***********************************************/??
??????
??? /**?
???? * @MethodName? : initCache?
???? * @Description : 初始化缓存?
???? */??
??? private void initCache(){??
??????? //1.创建cachemanager??
??? ?manager=CacheUtil.getCacheManager(IMemcachedCache.class,MemcachedCacheManager.class.getName());;
??????? //如果cache是空,則手動創建??
??????? if(cache==null){??
???manager.start();
???cache = (IMemcachedCache) manager.getCache("mclient1");
??????? }??
??? }??
??? /**?
???? * @MethodName? : getCache?
???? * @Description : 外部通过get方法拿到cache后,可清空cache?
???? * @return?
???? */??
??? public IMemcachedCache getCache() {??
??????? return cache;??
??? }??
?????
??? /**?
???? * @MethodName? : clearCache?
???? * @Description : 清理缓存?
???? */??
??? public void clearCache(){??
??????? if(cache!=null){??
??????????? cache.clear();
??????? }??
??? }
因为我是测试 所以利用EJB的拦截器
首先创建一个类对查询的方法进行缓存
@AroundInvoke??
??? public Object processCache(InvocationContext context) throws Exception{??
??????? String targetName = context.getTarget().getClass().getName();??
??????? String methodName = context.getMethod().getName();??
??????? Object[] arguments =context.getParameters();??
??????? Object result;??
??????? //获取缓存对象??
??????? IMemcachedCache cache = CacheHandler.getInstance().getCache();??
??????? //如果方法名以find、query、或get开头则执行缓存策略??
??????? if(methodName.startsWith("find") || methodName.startsWith("get") || methodName.startsWith("query")){??
??????????? String cacheKey = getCacheKey(targetName, methodName, arguments);??
??????????? Object element = cache.get(cacheKey);??
??????????? if (element == null) {??
??????????????? result = context.proceed(); // 执行目标方法,并保存目标方法执行后的返回值??
??????????????? cache.put(cacheKey, result);
??????????????? element=result;
??????????????? System.out.println("==========================createCache-->" + cacheKey);??
??????????? } else {??
??????????????? System.out.println("==========================hit Cache-->" + cacheKey);??
??????????? }??
??????????? return element;??
??????? }??
??????????
??????? //否则直接执行目标方法??
??????? return context.proceed();??
??? }??
??????
??? /**?
???? * @MethodName? : getCacheKey?
???? * @Description : 获得cache key的方法,cache key是Cache中一个Element的唯一标识 cache key包括?
???? * 包名+类名+方法名+各个参数的具体指,如com.jiwu.service.UserServiceImpl.getAllUser?
???? * @param targetName??? 类名?
???? * @param methodName??? 方法名?
???? * @param arguments???? 方法实参数组?
???? * @return????????????????????? cachekey?
???? */??
??? private String getCacheKey(String targetName, String methodName,??
??????????? Object[] arguments) {??
??????? StringBuffer sb = new StringBuffer();??
??????? sb.append(targetName).append(".").append(methodName);??
??????? if ((arguments != null) && (arguments.length != 0)) {??
??????????? for (int i = 0; i < arguments.length; i++) {??
??????????????? if(arguments[i] instanceof String[]){??
??????????????????? String[] strArray = (String[])arguments[i];??
??????????????????? sb.append(".");??
??????????????????? for(String str : strArray){??
??????????????????????? sb.append(str);??
??????????????????? }??
??????????????? }else{??
??????????????????? sb.append(".").append(arguments[i]);??
??????????????? }??
??????????????????
??????????? }??
??????? }??
??????????
??????? return sb.toString();??
??? }
然后manager引用的时候 只要在类上引用即可 例如以下
@Interceptors(CacheInterceptor.class)
public class AdminManagerImpl implements IAdminManager
这样的话就会对该类中所有的find,get,query 开始的方法进行拦截 缓存
?
由此整个EJB和memcache已关联,部署的时候还需要在deploy 同等目录的LIB下放入引用alisoft-xplatform-asf-cache-2.5.1.jar
?
OK启动你的JBOSS 打上你的断点看是否已经成功