包含javamemcachedset的词条

今天给各位分享javamemcachedset的知识,其中也会对进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

1、java中memcache怎么用2、如何配置Memcached服务器3、java框架有哪些常用框架4、如何最佳地使用memcached5、Memcached 在 Spring 里怎么用

java中memcache怎么用

1. memcached client for java客户端API:memcached client for java

引入jar包:java-memcached-2.6.2.jar

package com.pcitc.memcached;

import com.danga.MemCached.*;

public class TestMemcached {

public static void main(String[] args) {

/* 初始化SockIOPool,管理memcached的连接池 */

String[] servers = { “192.168.1.111:11211” };

SockIOPool pool = SockIOPool.getInstance();

pool.setServers(servers);

pool.setFailover(true);

pool.setInitConn(10);

pool.setMinConn(5);

pool.setMaxConn(250);

pool.setMaintSleep(30);

pool.setNagle(false);

pool.setSocketTO(3000);

pool.setAliveCheck(true);

pool.initialize();

/* 建立MemcachedClient实例 */

MemCachedClient memCachedClient = new MemCachedClient();

for (int i = 0; i 10; i++) {

/* 将对象加入到memcached缓存 */

boolean success = memCachedClient.set(“” + i, “Hello!”);

/* 从memcached缓存中按key值取对象 */

String result = (String) memCachedClient.get(“” + i);

System.out.println(String.format(“set( %d ): %s”, i, success));

System.out.println(String.format(“get( %d ): %s”, i, result));

}

}

}

2. spymemcached客户端API:spymemcached client

引入jar包:spymemcached-2.10.3.jar

package com.pcitc.memcached;

import java.net.InetSocketAddress;

import java.util.concurrent.Future;

import net.spy.memcached.MemcachedClient;

public class MClient {

public static void main(String[] args) {

setValue();

getValue();

}

// 用spymemcached将对象存入缓存

public static void setValue() {

try {

/* 建立MemcachedClient 实例,并指定memcached服务的IP地址和端口号 */

MemcachedClient mc = new MemcachedClient(new InetSocketAddress(

“192.168.1.111”, 11211));

FutureBoolean b = null;

/* 将key值,过期时间(秒)和要缓存的对象set到memcached中 */

b = mc.set(“neead”, 900, “someObject”);

if (b.get().booleanValue() == true) {

mc.shutdown();

}

} catch (Exception ex) {

ex.printStackTrace();

}

}

// 用spymemcached从缓存中取得对象

public static void getValue() {

try {

/* 建立MemcachedClient 实例,并指定memcached服务的IP地址和端口号 */

MemcachedClient mc = new MemcachedClient(new InetSocketAddress(

“192.168.1.111”, 11211));

/* 按照key值从memcached中查找缓存,不存在则返回null */

Object b = mc.get(“neead”);

mc.shutdown();

} catch (Exception ex) {

ex.printStackTrace();

}

}

}

3.两种API比较

memcached client for java:较早推出的memcached JAVA客户端API,应用广泛,运行比较稳定。

spymemcached:A simple, asynchronous, single-threaded memcached client written in java. 支持异步,单线程的memcached客户端,用到了java1.5版本的concurrent和nio,存取速度会高于前者,但是稳定性不好,测试中常报timeOut等相关异常。

由于memcached client for java发布了新版本,性能上有所提高,并且运行稳定,所以建议使用memcached client for java

如何配置Memcached服务器

Windows下的Memcache安装

1. 下载memcache的windows稳定版,解压放某个盘下面,比如在c:\memcached

2. 在终端(也即cmd命令界面)下输入 c:\memcached\memcached.exe -d install --安装memcached成为服务,这样才能正常运行,否则运行失败!

3. 再输入: c:\memcached\memcached.exe -d start --启动memcached的。

以后memcached将作为windows的一个服务每次开机时自动启动。这样服务器端已经安装完毕了。

Linux下的安装:

1.下载memcached和libevent,放到 /tmp 目录下

# cd /tmp

# wget

# wget

2.先安装libevent:

# tar zxvf libevent-1.2.tar.gz

# cd libevent-1.2

# ./configure –prefix=/usr

# make

# make install

3.测试libevent是否安装成功:

# ls -al /usr/lib | grep libevent

lrwxrwxrwx 1 root root 21 11?? 12 17:38 libevent-1.2.so.1 – libevent-1.2.so.1.0.3

-rwxr-xr-x 1 root root 263546 11?? 12 17:38 libevent-1.2.so.1.0.3

-rw-r–r– 1 root root 454156 11?? 12 17:38 libevent.a

-rwxr-xr-x 1 root root 811 11?? 12 17:38 libevent.la

lrwxrwxrwx 1 root root 21 11?? 12 17:38 libevent.so – libevent-1.2.so.1.0.3

4.安装memcached,同时需要安装中指定libevent的安装位置:

# cd /tmp

# tar zxvf memcached-1.2.0.tar.gz

# cd memcached-1.2.0

# ./configure –with-libevent=/usr

# make

# make install

如果中间出现报错,请仔细检查错误信息,按照错误信息来配置或者增加相应的库或者路径。

安装完成后会把memcached放到 /usr/local/bin/memcached ,

5.测试是否成功安装memcached:

# ls -al /usr/local/bin/mem*

-rwxr-xr-x 1 root root 137986 11?? 12 17:39 /usr/local/bin/memcached

-rwxr-xr-x 1 root root 140179 11?? 12 17:39 /usr/local/bin/memcached-debug

memcached的基本设置:

1.启动Memcache的服务器端:

# /usr/local/bin/memcached -d -m 10 -u root -l 192.168.0.200 -p 12000 -c 256 -P /tmp/memcached.pid

-d选项是启动一个守护进程,

-m是分配给Memcache使用的内存数量,单位是MB,这里是10MB,

-u是运行Memcache的用户,这里是root,

-l是监听的服务器IP地址,如果有多个地址的话,这里指定了服务器的IP地址192.168.0.200,

-p是设置Memcache监听的端口,这里设置了12000,最好是1024以上的端口,

-c选项是最大运行的并发连接数,默认是1024,这里设置了256,按照你服务器的负载量来设定,

-P是设置保存Memcache的pid文件,这里是保存在 /tmp/memcached.pid,

2.如果要结束Memcache进程,执行:

# kill `cat /tmp/memcached.pid`

也可以启动多个守护进程,不过端口不能重复。

3.重启apache,service httpd restart

java的客户端连接程序:

将java_memcached-release_1.6.zip解压后的目录中的java_memcached-release_2.0.jar文件复制到java项目的lib目录下。

package utils.cache;

import java.util.Date;

import com.danga.MemCached.MemCachedClient;

import com.danga.MemCached.SockIOPool;

/**

* 使用memcached的缓存实用类.

*/

public class MemCached

{

// 创建全局的唯一实例

protected static MemCachedClient mcc = new MemCachedClient();

protected static MemCached memCached = new MemCached();

// 设置与缓存服务器的连接池

static {

// 服务器列表和其权重

String[] servers = {“127.0.0.1:11211”};

Integer[] weights = {3};

// 获取socke连接池的实例对象

SockIOPool sockIOPool = SockIOPool.getInstance();

// 设置服务器信息

sockIOPool.setServers( servers );

sockIOPool.setWeights( weights );

// 设置初始连接数、最小和最大连接数以及最大处理时间

sockIOPool.setInitConn( 5 );

sockIOPool.setMinConn( 5 );

sockIOPool.setMaxConn( 250 );

sockIOPool.setMaxIdle( 1000 * 60 * 60 * 6 );

// 设置主线程的睡眠时间

sockIOPool.setMaintSleep( 30 );

// 设置TCP的参数,连接超时等

sockIOPool.setNagle( false );

sockIOPool.setSocketTO( 3000 );

sockIOPool.setSocketConnectTO( 0 );

//sockIOPool.setFailover(bFailover);

//sockIOPool.setAliveCheck(bAliveCheck);

// 初始化连接池

sockIOPool.initialize();

// 压缩设置,超过指定大小(单位为K)的数据都会被压缩

if (memCachedClient == null)

{

mcc = new MemCachedClient(sPoolName);

mcc.setCompressEnable(true);

mcc.setCompressThreshold(4096);

mcc.setPrimitiveAsString(true);

}

}

/*

h3基于Spring的配置,如下:/h3

pre

bean id=”memCachedService” class=”com.ms.memcached.MemCachedServiceImpl”

constructor-arg index=”0″ value=”${memcached.pool.name}” /

constructor-arg index=”1″ value=”${memcached.pool.servers}” /

constructor-arg index=”2″ value=”${memcached.pool.initConn}” /

constructor-arg index=”3″ value=”${memcached.pool.maxConn}” /

constructor-arg index=”4″ value=”${memcached.pool.minConn}” /

constructor-arg index=”5″ value=”${memcached.pool.socketTO}” /

constructor-arg index=”6″ value=”${memcached.pool.maintSleep}” /

constructor-arg index=”7″ value=”${memcached.pool.nagle}” /

constructor-arg index=”8″ value=”${memcached.pool.failover}” /

constructor-arg index=”9″ value=”${memcached.pool.aliveCheck}” /

/bean

/pre

h3利用com.MS.cache.properties来设置参数,如下:/h3

pre

memcached.pool.name = MS

memcached.pool.servers = 192.168.9.132:12000,192.168.9.133:12000

memcached.pool.initConn = 128

memcached.pool.maxConn = 1024

memcached.pool.minConn = 20

memcached.pool.socketTO = 3000

memcached.pool.maintSleep = 30

memcached.pool.nagle = false

memcached.pool.failover = true

memcached.pool.aliveCheck = true

/pre

*/

/**

* 保护型构造方法,不允许实例化!

*/

protected MemCached()

{

}

/**

* 获取唯一实例.

*/

public static MemCached getInstance()

{

return memCached;

}

/**

* 添加一个指定的值到缓存中.

* @param key

* @param value

*/

//新增指定key的缓存内容,但不覆盖已存在的内容。

public boolean add(String key, Object value)

{

return mcc.add(key, value);

}

//expiry过期时间

public boolean add(String key, Object value, Date expiry)

{

return mcc.add(key, value, expiry);

}

//新增或覆盖指定Key的缓存内容

public boolean set(String key, Object value)

{

return mcc.set(key, value);

}

//lExpiry过期时间

public boolean set(String key, Object value, long lExpiry)

{

return mcc.set(key, value, new Date(lExpiry));

}

//根据指定的Key获取缓存内容

public boolean get(String key)

{

return mcc.get(key);

}

//根据指定Key更新缓存内容

public boolean replace(String key, Object value)

{

return mcc.replace(key, value);

}

//lExpiry 指定的时间

public boolean replace(String key, Object value, long lExpiry)

{

return mcc.replace(key, value, new Date(lExpiry));

}

//根据指定Key删除缓存内容

public boolean delete(String key, Object value)

{

return mcc.delete(key, value);

}

//根据指定Key在指定时间后删除缓存内容

public boolean delete(String key, Object value, long lExpiry)

{

return mcc.delete(key, value, new Date(lExpiry));

}

//检测Cache中当前Key是否存在

public boolean exists(String key)

{

return mcc.exists(key);

}

//根据指定一批Key批量获取缓存内容。

/*

* @param sKeys 指定的一批Key。

* @return Object[oValue]

*/

public Object[] getMultiArray(String[] sKeys) throws ServiceException

{

return memCachedClient.getMultiArray(sKeys);

}

/**

* 根据指定一批Key批量获取缓存内容。

*

* @param sKeys 指定的一批Key。

* @return MapsKey, oValue

*/

public MapString, Object getMulti(String[] sKeys) throws ServiceException

{

return memCachedClient.getMulti(sKeys);

}

public static void main(String[] args)

{

MemCached memCached= MemCached.getInstance();

memCached.add(“hello”, 234);

System.out.print(“get value : ” + memCached.get(“hello”));

}

}

那么我们就可以通过简单的像main方法中操作的一样存入一个变量,然后再取出进行查看,我们可以看到先调用了add,然后再进行get,我们运行一次 后,234这个值已经被我们存入了memcached的缓存中的了,我们将main方法中红色的那一行注释掉后,我们再运行还是可以看到get到的 value也是234,即缓存中我们已经存在了数据了。

对基本的数据我们可以操作,对于普通的POJO而言,如果要进行存储的话,那么比如让其实现java.io.Serializable接口,因为 memcached是一个分布式的缓存服务器,多台服务器间进行数据共享需要将对象序列化的,所以必须实现该接口,否则会报错的。

Entity

/**

* 获取当前实体的缓存Id

*

* @return

*/

public String getCacheId()

{

return getCacheId(this.getClass(), sBreedId);

}

get

public Breed getBreedById(String sBreedId) throws ServiceException

{

Breed breed = (Breed)memCachedService.get(getCacheId(Breed.class, sBreedId));

if(breed == null)

{

breed = service.get(“breed.getBreedById”, sBreedId);

if(breed != null)

{

memCachedService.set(breed.getBreedId(), breed);

}

}

return breed;

}

save

memCachedService.set(spider.getCacheId(), breed);

update

memCachedService.replace(spider.getCacheId(), breed);

remove

memCachedService.delete(getCacheId(Spider.class, IbreedId));

memCachedService.delete(breed.getCacheId());

listAll

public List listAll() throws ServiceException

{

List breeds = new ArrayList ();

List breedIds = (List)memCachedService.get(getKeyByMap(“Breed”, null));

if(ObjectUtils.isEmpty(breedIds))

{

breeds = service.list(“breed.getAllBreed”, null);

if (!ObjectUtils.isEmpty(breeds))

{

breedIds = new ArrayList();

for (Breed breed : breeds)

{

breedIds.add(breed.getBreedId());

}

memCachedService.set(getKeyByMap(“Breed”, null), breedIds);

}

}

else

{

for (String sBreedId : breedIds)

{

Breed breed = getBreedById(sBreedId);

if (breed != null)

{

breeds.add(breed);

}

}

}

return breeds;

}

包含javamemcachedset的词条

java框架有哪些常用框架

十大常用框架:

一、SpringMVC

二、Spring

三、Mybatis

四、Dubbo

五、Maven

六、RabbitMQ

七、Log4j

八、Ehcache

九、Redis

十、Shiro

延展阅读:

一、SpringMVC

Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助我们简化开发,Spring Web MVC也是要简化我们日常Web开发的。

模型(Model )封装了应用程序的数据和一般他们会组成的POJO。

视图(View)是负责呈现模型数据和一般它生成的HTML输出,客户端的浏览器能够解释。

控制器(Controller )负责处理用户的请求,并建立适当的模型,并把它传递给视图渲染。

Spring的web模型 – 视图 – 控制器(MVC)框架是围绕着处理所有的HTTP请求和响应的DispatcherServlet的设计。

Spring Web MVC处理请求的流程

具体执行步骤如下:

1、 首先用户发送请求————前端控制器,前端控制器根据请求信息(如URL)来决定选择哪一个页面控制器进行处理并把请求委托给它,即以前的控制器的控制逻辑部分;图2-1中的1、2步骤;

2、 页面控制器接收到请求后,进行功能处理,首先需要收集和绑定请求参数到一个对象,这个对象在Spring Web MVC中叫命令对象,并进行验证,然后将命令对象委托给业务对象进行处理;处理完毕后返回一个ModelAndView(模型数据和逻辑视图名);图2-1中的3、4、5步骤;

3、 前端控制器收回控制权,然后根据返回的逻辑视图名,选择相应的视图进行渲染,并把模型数据传入以便视图渲染;图2-1中的步骤6、7;

4、 前端控制器再次收回控制权,将响应返回给用户,图2-1中的步骤8;至此整个结束。

二、Spring

2.1、IOC容器:

IOC容器就是具有依赖注入功能的容器,IOC容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。应用程序无需直接在代码中new相关的对象,应用程序由IOC容器进行组装。在Spring中BeanFactory是IOC容器的实际代表者。

2.2、AOP:

简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。AOP代表的是一个横向的关系

AOP用来封装横切关注点,具体可以在下面的场景中使用:

Authentication 权限 

Caching 缓存 

Context passing 内容传递 

Error handling 错误处理 

Lazy loading 懒加载 

Debugging调试 

logging, tracing, profiling and monitoring 记录跟踪 优化 校准 

Performance optimization 性能优化 

Persistence持久化 

Resource pooling 资源池 

Synchronization 同步 

Transactions 事务

三、Mybatis

MyBatis 是支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。

总体流程:

(1)加载配置并初始化 

触发条件:加载配置文件 

将SQL的配置信息加载成为一个个MappedStatement对象(包括了传入参数映射配置、执行的SQL语句、结果映射配置),存储在内存中。

(2)接收调用请求 

触发条件:调用Mybatis提供的API 

传入参数:为SQL的ID和传入参数对象 

处理过程:将请求传递给下层的请求处理层进行处理。

(3)处理操作请求 触发条件:API接口层传递请求过来 

传入参数:为SQL的ID和传入参数对象

处理过程:

(A)根据SQL的ID查找对应的MappedStatement对象。

(B)根据传入参数对象解析MappedStatement对象,得到最终要执行的SQL和执行传入参数。

(C)获取数据库连接,根据得到的最终SQL语句和执行传入参数到数据库执行,并得到执行结果。

(D)根据MappedStatement对象中的结果映射配置对得到的执行结果进行转换处理,并得到最终的处理结果。

(E)释放连接资源。

(4)返回处理结果将最终的处理结果返回。

MyBatis 最强大的特性之一就是它的动态语句功能。如果您以前有使用JDBC或者类似框架的经历,您就会明白把SQL语句条件连接在一起是多么的痛苦,要确保不能忘记空格或者不要在columns列后面省略一个逗号等。动态语句能够完全解决掉这些痛苦。

四、Dubbo

Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC(远程过程调用协议)远程服务调用方案,以及SOA服务治理方案。简单的说,dubbo就是个服务框架,如果没有分布式的需求,其实是不需要用的,只有在分布式的时候,才有dubbo这样的分布式服务框架的需求,并且本质上是个服务调用的东东,说白了就是个远程服务调用的分布式框架。

1、透明化的远程方法调用,就像调用本地方法一样调用远程方法,只需简单配置,没有任何API侵入。

2、软负载均衡及容错机制,可在内网替代F5等硬件负载均衡器,降低成本,减少单点。

3、 服务自动注册与发现,不再需要写死服务提供方地址,注册中心基于接口名查询服务提供者的IP地址,并且能够平滑添加或删除服务提供者。

节点角色说明: 

Provider: 暴露服务的服务提供方。 

Consumer: 调用远程服务的服务消费方。 

Registry: 服务注册与发现的注册中心。 

Monitor: 统计服务的调用次调和调用时间的监控中心。 

Container: 服务运行容器。

五、Maven

Maven这个个项目管理和构建自动化工具,越来越多的开发人员使用它来管理项目中的jar包。但是对于我们程序员来说,我们最关心的是它的项目构建功能。

六、RabbitMQ

消息队列一般是在项目中,将一些无需即时返回且耗时的操作提取出来,进行了异步处理,而这种异步处理的方式大大的节省了服务器的请求响应时间,从而提高了系统的吞吐量。

RabbitMQ是用Erlang实现的一个高并发高可靠AMQP消息队列服务器。

Erlang是一门动态类型的函数式编程语言。对应到Erlang里,每个Actor对应着一个Erlang进程,进程之间通过消息传递进行通信。相比共享内存,进程间通过消息传递来通信带来的直接好处就是消除了直接的锁开销(不考虑Erlang虚拟机底层实现中的锁应用)。

AMQP(Advanced Message Queue Protocol)定义了一种消息系统规范。这个规范描述了在一个分布式的系统中各个子系统如何通过消息交互。

七、Log4j

日志记录的优先级,分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者您定义的级别。

八、Ehcache

EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认的CacheProvider。Ehcache是一种广泛使用的开源Java分布式缓存。主要面向通用缓存,Java EE和轻量级容器。它具有内存和磁盘存储,缓存加载器,缓存扩展,缓存异常处理程序,一个gzip缓存servlet过滤器,支持REST和SOAP api等特点。

优点: 

1、 快速 

2、 简单 

3、 多种缓存策略 

4、缓存数据有两级:内存和磁盘,因此无需担心容量问题 

5、 缓存数据会在虚拟机重启的过程中写入磁盘 

6、可以通过RMI、可插入API等方式进行分布式缓存 

7、 具有缓存和缓存管理器的侦听接口 

8、支持多缓存管理器实例,以及一个实例的多个缓存区域 

9、提供Hibernate的缓存实现

缺点: 

1、使用磁盘Cache的时候非常占用磁盘空间:这是因为DiskCache的算法简单,该算法简单也导致Cache的效率非常高。它只是对元素直接追加存储。因此搜索元素的时候非常的快。如果使用DiskCache的,在很频繁的应用中,很快磁盘会满。

2、 不能保证数据的安全:当突然kill掉java的时候,可能会产生冲突,EhCache的解决方法是如果文件冲突了,则重建cache。这对于Cache数据需要保存的时候可能不利。当然,Cache只是简单的加速,而不能保证数据的安全。如果想保证数据的存储安全,可以使用Bekeley DB Java Edition版本。这是个嵌入式数据库。可以确保存储安全和空间的利用率。

九、Redis

redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set –有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。

Redis数据库完全在内存中,使用磁盘仅用于持久性。相比许多键值数据存储,Redis拥有一套较为丰富的数据类型。Redis可以将数据复制到任意数量的从服务器。

1.2、Redis优点:

(1)异常快速:Redis的速度非常快,每秒能执行约11万集合,每秒约81000+条记录。

(2)支持丰富的数据类型:Redis支持最大多数开发人员已经知道像列表,集合,有序集合,散列数据类型。这使得它非常容易解决各种各样的问题,因为我们知道哪些问题是可以处理通过它的数据类型更好。

(3)操作都是原子性:所有Redis操作是原子的,这保证了如果两个客户端同时访问的Redis服务器将获得更新后的值。

(4)多功能实用工具:Redis是一个多实用的工具,可以在多个用例如缓存,消息,队列使用(Redis原生支持发布/订阅),任何短暂的数据,应用程序,如Web应用程序会话,网页命中计数等。

1.3、Redis缺点: 

(1)单线程 

(2)耗内存

十、Shiro

Apache Shiro是Java的一个安全框架,旨在简化身份验证和授权。Shiro在JavaSE和JavaEE项目中都可以使用。它主要用来处理身份认证,授权,企业会话管理和加密等。Shiro的具体功能点如下:

(1)身份认证/登录,验证用户是不是拥有相应的身份;

(2)授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限;

(3)会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通JavaSE环境的,也可以是如Web环境的;

(4)加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;

(5)Web支持,可以非常容易的集成到Web环境; 

Caching:缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可以提高效率;

(6)shiro支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去;

(7)提供测试支持;

(8)允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;

(9)记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了。

如何最佳地使用memcached

如何最佳地使用memcached?

Memcached是由DangaInteractive开发的,高性能的,分布式的内存对象缓存系统,如何最佳地使用memcached,以提升站点性能?大家一起来了解一下。

一、Memcached简介

memcached 常被用来加速应用程序的处理,在这里,我们将着重于介绍将它部署于应用程序和环境中的最佳实践。这包括应该存储或不应存储哪些、如何处理数据的灵活分布以 及如何调节用来更新 memcached 和所存储数据的方法。我们还将介绍对高可用性的解决方案的支持,比如 IBM WebSphere® eXtreme Scale。

所有的应用程序,特别是很多 web 应用程序都需要优化它们访问客户机和将信息返回至客户机的速度。可是,通常,返回的都是相同的信息。从数据源(数据库或文件系统)加载数据十分低效,若是每次想要访问该信息时都运行相同的查询,就尤显低效。

虽然很多 web 服务器都可被配置成使用缓存发回信息,但那与大多数应用程序的动态特性无法相适。而这正是 memcached 的用武之地。它提供了一个通用的内存存储器,可保存任何东西,包括本地语言的对象,这就让您可以存储各种各样的信息并可以从诸多的应用程序和环境访问这些信息。

二、基础知识

memcached 是一个开源项目,旨在利用多个服务器内的多余 RAM 来充当一个可存放经常被访问信息的内存缓存。这里的关键是使用了术语缓存:memcached 为加载自他处的信息提供的是内存中的暂时存储。

比如,考虑这样一个典型的基于 web 的应用程序。即便是一个动态网站可能也会有一些组件或信息常量是贯穿页面整个生命周期的。在一个博客站点内,针对单个 blog post 的类别列表不大可能在页面查看间经常性地变更。每次都通过一个对数据库的查询加载此信息相对比较昂贵,特别是在数据没有更改的情况下,就更是如此。从图 1 可以看到一个博客站点内可被缓存的页面分区。

图1.一个典型的博客页面内的可缓存元素

将这种结构放在 blog 站点的其他元素,poster 信息、注释 — 设置 blog post 本身 — 进行推断,可以看出为了显示主页的内容很可能需要发生 10-20 次数据库查询和格式化。 每天对数百甚至数千的的页面查看重复此过程,那么您的服务器和应用程序执行的查询要远远多于为了显示页面内容所需执行的查询。

通过使用 memcached,可以将加载自数据库的格式化信息存储为一种可直接用在 Web 页面上的格式。并且由于信息是从 RAM 而不是通过数据库和其他处理从磁盘加载的,所以对信息的访问几乎是瞬时的。

再强调一下,memcached 是一个用来存储常用信息的缓存,有了它,您便无需从缓慢的资源,比如磁盘或数据库,加载并处理信息了。

对 memcached 的接口是通过网络连接提供的。这意味着您可以在多个客户机间共享单个的 memcached 服务器(或多个服务器,如本文稍后所示的)。这个网络接口非常迅速,并且为了改善性能,服务器会故意不支持身份验证或安全性通信。但这不应限制部署选项。 memcached 服务器应该存在于您网络的内部。网络接口的实用性以及可以部署多个 memcached 实例的简便性让您可以使用多个机器上的多余 RAM 来提高您缓存的整体大小。

三、存储方法

memcached 的存储方法是一个简单的键/值对,类似于很多语言内的散列或关联数组。通过提供键和值来将信息存储到 memcached 内,通过按特定的键请求信息来恢复信息。

信息会无限期地保留在缓存内,除非发生如下的情况:

为缓存分配的内存耗尽 — 在这种情况下,memcached 使用 LRU(最近最少使用)方法从此缓存删除条目。最近未曾使用的条目会从此缓存中先删除,最旧的最先访问。

条目被明确删除 — 总是可以从此缓存内删除条目。

条目过期失效 — 各条目均有一个有效的期限以便针对此键存储的信息在过于陈旧时可从缓存中清除这些条目。

上述这些情况可以与您应用程序的逻辑综合使用以便确保缓存内的信息是最新的。有了这些基础知识后,让我们来看看在应用程序内如何能最好地利用 memcached。

四、何时使用memcached?

在使用 memcached 改进应用程序性能时,可以对一些关键的过程和步骤进行修改。

在加载信息时,典型的场景如图 2 所示。

图2.加载要显示的信息的典型顺序

一般而言,这些步骤是:

执行一个或多个查询来从数据库加载信息

格式化适合于显示(或进一步处理)的信息

使用或显示格式化了的数据

在使用 memcached 时,为配合这个缓存,可对应用程序的逻辑进行稍许修改:

尽量从缓存加载信息

如果存在,使用信息的被缓存版本

如果它不存在:

执行一个或多个查询来从数据库加载信息

格式化适合于显示或进一步处理的信息

将信息存储到缓存内

使用格式化了的数据

图 3 是对这些步骤的总结。

图3.在使用memcached时加载适合于显示的信息

数据加载成为了至多三个步骤的一个过程,从缓存加载数据或从数据库(视情况而定)加载数据并存储在缓存内。

当这个过程首次发生时,数据将正常地从数据库或其他数据源加载,然后再存储到 memcached 内。当下一次访问此信息时,它就会从 memcached 拉出,而不是从数据库加载,节省了时间和 CPU 循环。

问题的另一个方面是要确保如果更改了要存储在 memcached 内的信息,在更新后端信息的同时还要更新 memcached 的版本。这会让图 4 内所示的这个典型顺序发生稍许变化,如 图 5 所示。

图4.在一个典型的应用程序内更新或存储数据

图 5 显示了使用 memcached 后发生了变化的流程。

图5.在使用memcached时更新或存储数据

比如,仍以博客站点为例,在博客系统更新数据库内的类别列表时,更新应该遵循如下顺序:

更新数据库内的类别列表

格式化信息

将信息存储到 memcached 内

将信息返回至客户机

memcached 内的存储操作是原子的,所以信息的更新不会让客户机只获得部分数据;它们获得的或者是老版本,或者是新版本。

对于大多数应用程序,这两个操作是您惟一需要注意的。在访问他人使用的数据时,它会自动被添加到这个缓存内,而且如果对该数据进行了更改,此缓存内也会自动进行更新。

五、键、名称空间和值

memcached 另一个需要重点考虑的因素是如何组织和命名存储在缓存内的这些数据。从之前博客站点的例子中,不难看出需要使用一种一致的命名结构以便您能加载博客类别、历史和其他信息,然后再在加载信息(并更新缓存)时或者在更新数据(同样也要更新缓存)时使用。

使用的何种具体的命名系统特定于应用程序,但通常可以使用一种与现有应用程序类似的结构,并且这种结构很可能基于某种惟一识别符。当从数据库拉出信息或在整理信息集时,就会发生这种情况。

以 blog post 为例,可以在一个具有键 category-list 的项中存储类别列表。与此 post ID 对应的单个 post,比如 blogpost-29 相关的值都可以使用,而该项的注释则可以存储在 blogcomments-29内,其中 29 就是这个 blog post 的 ID。这样一来, 您就可以将各种各样的信息存储在缓存内,使用不同的前缀来标识这些信息。

memcached 键/值存储的简便性(以及安全性的缺乏)意味着如果您想要在使用同一个 memcached 服务器的同时支持多个应用程序,那么就可以考虑使用其他格式的量词来标识数据属于某种特定的应用程序。比如,可以添加像 blogapp:blogpost-29 这样的应用程序前缀。这些键是没有格式的,所以可以使用任何字符串作为键的名称。

在存储值的方面,应该确保存储在缓存内的信息适合于您的应用程序。比如,对于这个博客系统,您可能想要存储被博客应用程序使用的对象以便格式化博客信息,而不是原始的 HTML。如果同一个基础结构用在应用程序内的多个地方,这一点更具实用性。

大多数语言的接口,包括 Java™、Perl、PHP 等,都能串行化语言对象以便存储在 memcached 内。这就让您可以存储并随后从内存存储恢复全部对象,而不是在您的应用程序内手动重构它们。 很多对象,或它们使用的结构,都基于某种散列或数组结构。对于跨语言的环境,比如在 JSP 环境和 JavaScript 环境间共享相同信息,可以使用一种架构中立的格式,比如 JavaScript Object Notation (JSON) 甚或 XML。

六、填充并使用memcached

作为一种开源产品以及一种最初开发用来工作于现有开源环境内的产品,memcached 受大量环境和平台支持。与 memcached 服务器通信的接口有很多,并常常具有针对所有语言的多个实现。参见参考资料 以获得常用的库和工具箱。

要列出所有受支持的接口和环境不太可能,但它们均支持 memcached 协议提供的基础 API。这些描述已经被简化并应用在不同语言的上下文内,在这些语言中,使用不同的值可指示错误。主要的函数有:

get(key) — 从存储了特定键的 memcached 获得信息。 如果键不存在,就返回错误。

set(key, value [, expiry]) — 使用缓存内的标识符键存储这个特定的值。如果键已经存在,那么它就会被更新。期满时间的单位为秒,并且如果值小于 30 天 (30*24*60*60),那么就用作相对时间,如果值大于 30 天,那么就用作绝对时间 (epoch)。

add(key, value [, expiry]) — 如果键不存在就将这个键添加到缓存内,如果键已经存在就返回错误。如果您想要显式地添加一个新键而又不会因它已经存在而更新它,那么这个函数将十分有用。

replace(key, value [, expiry]) — 更新此特定键的值,如果键不存在就返回一个错误。

delete(key [, time]) — 从缓存中删除此键/值对。如果您提供一个时间,那么添加具有此键的一个新值就会被阻塞这个特定的时期。超时让您可以确保此值总是可以重新读取自您的数据中心。

incr(key [, value]) — 为特定的键增 1 或特定的值。只适用于数值。

decr(key [, value]) — 为特定的键减 1 或特定的值,只适用于数值。

flush_all — 让缓存内的所有当前条目无效(或到期失效)。

比如,在 Perl 内,基本 set 操作可以如清单 1 所示的那样处理。

清单 1. Perl 内的基本 set 操作

use Cache::Memcached;

my $cache = new Cache::Memcached {

‘servers’ = [

‘www.easyaq.com:11211’,

],

};

$cache-set(‘mykey’, ‘myvalue’);

Ruby 内的相同的基本操作如清单 2 所示。

清单 2. Ruby 内的基本 set 操作

require ‘memcache’

memc = MemCache::new ‘192.168.0.100:11211’

memc[“mykey”] = “myvalue”

在两个例子中可以看到相同的基本结构:设置 memcached 服务器,然后分配或设置值。其他的接口也可用,包括适合于 Java 技术的那些接口,让您可以在 WebSphere 应用程序内使用 memcached。memcached 接口类允许将 Java 对象直接序列化到 memcached 以便于存储和加载复杂的结构。当在像 WebSphere 这样的环境内进行部署时,有两个事情非常重要:服务的弹性(在 memcached 不可用时如何做)以及如何提高缓存存储量来改进在使用多个应用程序服务器或在使用像 WebSphere eXtreme Scale 这样的环境时的性能。我们接下来就来看看这两个问题。

七、弹性和可用性

有关 memcached 最常见的一个问题是:“若缓存不可用了,会发生什么情况呢?”正如之前章节中明示的,缓存内的信息不应该成为信息的的惟一资源。必须要能够从其他位置加载存储在缓存内的数据。

虽然,无法从缓存访问信息将会减缓应用程序的性能,但它不应该阻止应用程序的运转。可能会发生这样几个场景:

如果 memcached 服务宕掉,应用程序应该回退到从原始数据源加载信息并对信息进行显示所需的格式化。此应用程序还应继续尝试在 memcached 内加载和存储信息。

一旦 memcached 服务器恢复可用,应用程序就应该自动尝试存储数据。没有必要强制重载已缓存了的数据,可以使用标准的访问来用信息加载和填充缓存。最终,缓存将会被最常用的数据重新填充。

再次重申,memcached 是信息的缓存但并非惟一的数据源。memcached 服务器不可用不应该是应用程序的终结,虽然这意味着在 memcached 服务器恢复正常之前性能会有所降低。实际上,memcached 服务器相对简单,并且虽然不是绝对无故障的,但它的简单性的结果就是它很少会出错。

八、分配缓存

memcached 服务器只是网络上针对一些键存储值的一个缓存。如果有多台机器,那么很自然地会想要在所有多余机器上设置一个 memcached 的实例来提供一个超大的联网 RAM 缓存存储。

有了这个想法后,还有一种想当然是需要使用某种分配或复制机制来在机器之间复制键/值对。这种方式的问题是如果这么做反而会减少可用的 RAM 缓存,而不是增加。如图 6 所示,可以看出这里有三个应用程序服务器,每个服务器都可以访问一个 memcached 实例。

图6.多重memcached实例的不正确使用

尽管每个 memcached 实例都是 1 GB 的大小(产生 3 GB 的 RAM 缓存),但如果每个应用程序服务器只有其自己的缓存(或者在 memcached 之间存在着数据的复制),那么整个安装也仍只能有 1 GB 的缓存在每个实例间复制。

由于 memcached 通过一个网络接口提供信息,因此单个的客户机可以从它所能访问的任何一个 memcached 实例访问数据。如果数据没有跨每个实例被复制,那么最终在每个应用程序服务器上,就可以有 3 GB 的 RAM 缓存可用,如图 7 所示。

图7.多重memcached实例的正确使用

这个方法的问题是选择哪个服务器来储存键/值对,以及当想要重新获得一个值时,如何决定要与哪个 memcached 服务器对话。问题的解决方案就是忽略复杂的东西,比如查找表,或是寄望 memcached 服务器来为您处理这个过程。而 memcached 客户机则必须要力求简单。

memcached 客户机不必决定此信息,它只需对在存储信息时指定的键使用一个简单的散列算法。当想要从一列 memcached 服务器存储或获取信息时,memcached 客户机就会用一个一致的散列算法从这个键获取一个数值。举个例子,键 mykey 被转换成数值 23875 。是保存还是获取信息无关紧要,这个键将总是被用作惟一标识符来从 memcached 服务器加载,因此在本例中,“mykey” 散列转化后对应的值总是 23875。

如果有两个服务器,那么 memcached 客户机将对这个数值进行一个简单的运算(例如,系数)来决定它应将此值存储在第一个还是第二个配置了的 memcached 实例上。

当存储一个值时,客户机会从这个键确定出散列值以及它原来存储在哪个服务器上。当获取一个值时,客户机会从这个键确定出相同的散列值并会选择相同的服务器来获取信息。

如果在每个应用程序服务器上使用的是相同的服务器列表(并且顺序相同),那么当需要保存或检索同一个键时,每个应用程序服务器都将选择同一个 服务器。现在,在这个例子中,有 3GB 的 memcached 空间可以共享,而不是同一个 1 GB 的空间的复制,这就带来了更多的可用缓存,并很有可能会提高有多个用户情况下的应用程序的性能。

九、如何能不使用memcached?

尽管 memcached 很简单,但 memcached 实例有时候还是会被不正确地使用。

memcached不是一个数据库

最常见的 memcached 误用就是把它用作一个数据存储,而不是一个缓存。memcached 的首要目的就是加快数据的响应时间,否则数据从其他数据源构建或恢复需要很长时间。一个典型的例子就是从一个数据库中恢复信息,特别是在信息显示给用户前 需要对信息进行格式化或处理的时候。Memcached 被设计用来将信息存储在内存中以避免每次在数据需要恢复时重复执行相同的任务。

切不可将 memcached 用作运行应用程序所需信息的惟一信息源;数据应总是可以从其他信息源获取。此外,要记住 memcached 只是一个键/值的存储。不能在数据上执行查询,或者对内容进行迭代来提取信息。应该使用它来存储数据块或对象以备批量使用。

不要缓存数据库行或文件

虽然可以使用 memcached 存储加载自数据库的数据行,但这实际上是查询缓存,并且大多数数据库都提供各自的查询缓存的机制。其他的对象,比如文件系统的图像或文件的情况与此相同。很多应用程序和 web 服务器针对此类工作已经有了一些很好的解决方案。

如果在加载和格式化后,使用它来存储全部信息块,就可以从 memcached 获得更多的实用工具和性能上的改善。仍以我们的博客站点为例,存储信息的最佳点是在将博客类别格式化为对象,甚至是在格式化成 HTML 后。博客页面的构造可通过从 memcached 加载各个组件(比如 blog post、category list、post history 等)并将完成的 HTML 写回至客户机实现。

memcached并不安全

为了确保最佳性能,memcached 并未提供任何形式的安全性,没有身份验证,也没有加密。这意味着对 memcached 服务器的访问应该这么处理:一是通过将它们放到应用程序部署环境相同的私有侧,二是如果安全性是必须的,那么就使用 UNIX® socket 并只允许当前主机上的应用程序访问此 memcached 服务器。

这多少牺牲了一些灵活性和弹性,以及跨网络上的多台机器共享 RAM 缓存的能力,但这是在目前的情况下确保 memcached 数据安全性的惟一一种解决方案。

十、不要限制自己

除了不应该使用 memcached 实例的情况外,memcached 的灵活性不应忽视。由于 memcached 与应用程序处于相同的架构水平,所以很容易集成并连接到它。并且更改应用程序以便利用 memcached 也并不复杂。此外,由于 memcached 只是一个缓存,所以在出现问题时它不会停止应用程序的执行。如果使用正确的话,它所做的是减轻其余服务器基础设施的负载(减少对数据库和数据源的读操 作),这意味着无需更多的硬件就可以支持更多的客户机。

但请记住,它仅仅是个缓存!

结束语

在本文中,我们了解了 memcached 以及如何最佳地使用它。我们看到了信息如何存储、如何选择合理的键以及如何选择要存储的信息。我们还讨论了所有 memcached 用户都要遇到的一些关键的部署问题,包括多服务器的使用、当 memcached 实例消亡时该怎么做,以及(也许最为重要的)在哪些情况下不能使用 memcached。

作为一种开源的应用程序并且是目的简单而直白的应用程序,memcached 的功能和实用性均来自于这种简单性。通过为信息提供巨大的 RAM 存储空间、让它在网络上可用,然后再让它可通过各种不同的接口和语言访问到,memcached 可被集成到多种多样的安装和环境中。

Memcached 在 Spring 里怎么用

本文将对在Java环境下Memcached应用进行详细介绍。Memcached主要是集群环境下的缓存解决方案,可以运行在Java或者.NET平台上,这里我们主要讲的是Windows下的Memcached应用。

这些天在设计SNA的架构,接触了一些远程缓存、集群、session复制等的东西,以前做企业应用的时候感觉作用不大,现在设计面对internet的系统架构时就非常有用了,而且在调试后看到压力测试的情况还是比较好的。

在缓存的选择上有过很多的思考,虽然说memcached结合java在序列化上性能不怎么样,不过也没有更好的集群环境下的缓存解决方案了,就选择了memcached。本来计划等公司买的服务器到位装个linux再来研究memcached,但这两天在找到了一个windows下的Memcached版本,就动手开始调整现有的框架了。

Windows下的Server端很简单,不用安装,双击运行后默认服务端口是11211,没有试着去更改端口,因为反正以后会用Unix版本,到时再记录安装步骤。下载客户端的JavaAPI包,接口非常简单,参考API手册上就有现成的例子。

目标,对旧框架缓存部分进行改造:

1、缓存工具类

2、hibernate的provider

3、用缓存实现session机制

今天先研究研究缓存工具类的改造,在旧框架中部分函数用了ehcache对执行结果进行了缓存处理,现在目标是提供一个缓存工具类,在配置文件中配置使用哪种缓存(memcached或ehcached),使其它程序对具体的缓存不依赖,同时使用AOP方式来对方法执行结果进行缓存。

首先是工具类的实现:

在Spring中配置

Java代码

bean id=”cacheManager”

class=”org.springframework.cache.ehcache.EhCacheManagerFactoryBean”

property name=”configLocation”

valueclasspath:ehcache.xmlvalue

property

bean

bean id=”localCache”

class=”org.springframework.cache.ehcache.EhCacheFactoryBean”

property name=”cacheManager” ref=”cacheManager” /

property name=”cacheName”

value=”×××.cache.LOCAL_CACHE” /

bean

bean id=”cacheService”

class=”×××.core.cache.CacheService” init-method=”init” destroy-method=”destory”

property name=”cacheServerList” value=”${cache.servers}”/

property name=”cacheServerWeights” value=”${cache.cacheServerWeights}”/

property name=”cacheCluster” value=”${cache.cluster}”/

property name=”localCache” ref=”localCache”/

bean

bean id=”cacheManager”

class=”org.springframework.cache.ehcache.EhCacheManagerFactoryBean”

property name=”configLocation”

valueclasspath:ehcache.xmlvalue

property

bean

bean id=”localCache”

class=”org.springframework.cache.ehcache.EhCacheFactoryBean”

property name=”cacheManager” ref=”cacheManager” /

property name=”cacheName”

value=”×××.cache.LOCAL_CACHE” /

bean

bean id=”cacheService”

class=”×××.core.cache.CacheService” init-method=”init” destroy-method=”destory”

property name=”cacheServerList” value=”${cache.servers}”/

property name=”cacheServerWeights” value=”${cache.cacheServerWeights}”/

property name=”cacheCluster” value=”${cache.cluster}”/

property name=”localCache” ref=”localCache”/

bean

在properties文件中配置${cache.servers} ${cache.cacheServerWeights} ${cache.cluster}

具体工具类的代码

Java代码

/**

* @author Marc

*

*/

public class CacheService {

private Log logger = LogFactory.getLog(getClass());

private Cache localCache;

String cacheServerList;

String cacheServerWeights;

boolean cacheCluster = false;

int initialConnections = 10;

int minSpareConnections = 5;

int maxSpareConnections = 50;

long maxIdleTime = 1000 * 60 * 30; // 30 minutes

long maxBusyTime = 1000 * 60 * 5; // 5 minutes

long maintThreadSleep = 1000 * 5; // 5 seconds

int socketTimeOut = 1000 * 3; // 3 seconds to block on reads

int socketConnectTO = 1000 * 3; // 3 seconds to block on initial

// connections. If 0, then will use blocking

// connect (default)

boolean failover = false; // turn off auto-failover in event of server

// down

boolean nagleAlg = false; // turn off Nagle’s algorithm on all sockets in

// pool

MemCachedClient mc;

public CacheService(){

mc = new MemCachedClient();

mc.setCompressEnable(false);

}

/**

* 放入

*

*/

public void put(String key, Object obj) {

Assert.hasText(key);

Assert.notNull(obj);

Assert.notNull(localCache);

if (this.cacheCluster) {

mc.set(key, obj);

} else {

Element element = new Element(key, (Serializable) obj);

localCache.put(element);

}

}

/**

* 删除

*/

public void remove(String key){

Assert.hasText(key);

Assert.notNull(localCache);

if (this.cacheCluster) {

mc.delete(key);

}else{

localCache.remove(key);

}

}

/**

* 得到

*/

public Object get(String key) {

Assert.hasText(key);

Assert.notNull(localCache);

Object rt = null;

if (this.cacheCluster) {

rt = mc.get(key);

} else {

Element element = null;

try {

element = localCache.get(key);

} catch (CacheException cacheException) {

throw new DataRetrievalFailureException(“Cache failure: “

+ cacheException.getMessage());

}

if(element != null)

rt = element.getValue();

}

return rt;

}

/**

* 判断是否存在

*

*/

public boolean exist(String key){

Assert.hasText(key);

Assert.notNull(localCache);

if (this.cacheCluster) {

return mc.keyExists(key);

}else{

return this.localCache.isKeyInCache(key);

}

}

private void init() {

if (this.cacheCluster) {

String[] serverlist = cacheServerList.split(“,”);

Integer[] weights = this.split(cacheServerWeights);

// initialize the pool for memcache servers

SockIOPool pool = SockIOPool.getInstance();

pool.setServers(serverlist);

pool.setWeights(weights);

pool.setInitConn(initialConnections);

pool.setMinConn(minSpareConnections);

pool.setMaxConn(maxSpareConnections);

pool.setMaxIdle(maxIdleTime);

pool.setMaxBusyTime(maxBusyTime);

pool.setMaintSleep(maintThreadSleep);

pool.setSocketTO(socketTimeOut);

pool.setSocketConnectTO(socketConnectTO);

pool.setNagle(nagleAlg);

pool.setHashingAlg(SockIOPool.NEW_COMPAT_HASH);

pool.initialize();

logger.info(“初始化memcached pool!”);

}

}

private void destory() {

if (this.cacheCluster) {

SockIOPool.getInstance().shutDown();

}

}

}

/**

* @author Marc

*

*/

public class CacheService {

private Log logger = LogFactory.getLog(getClass());

private Cache localCache;

String cacheServerList;

String cacheServerWeights;

boolean cacheCluster = false;

int initialConnections = 10;

int minSpareConnections = 5;

int maxSpareConnections = 50;

long maxIdleTime = 1000 * 60 * 30; // 30 minutes

long maxBusyTime = 1000 * 60 * 5; // 5 minutes

long maintThreadSleep = 1000 * 5; // 5 seconds

int socketTimeOut = 1000 * 3; // 3 seconds to block on reads

int socketConnectTO = 1000 * 3; // 3 seconds to block on initial

// connections. If 0, then will use blocking

// connect (default)

boolean failover = false; // turn off auto-failover in event of server

// down

boolean nagleAlg = false; // turn off Nagle’s algorithm on all sockets in

// pool

MemCachedClient mc;

public CacheService(){

mc = new MemCachedClient();

mc.setCompressEnable(false);

}

/**

* 放入

*

*/

public void put(String key, Object obj) {

Assert.hasText(key);

Assert.notNull(obj);

Assert.notNull(localCache);

if (this.cacheCluster) {

mc.set(key, obj);

} else {

Element element = new Element(key, (Serializable) obj);

localCache.put(element);

}

}

/**

* 删除

*/

public void remove(String key){

Assert.hasText(key);

Assert.notNull(localCache);

if (this.cacheCluster) {

mc.delete(key);

}else{

localCache.remove(key);

}

}

/**

* 得到

*/

public Object get(String key) {

Assert.hasText(key);

Assert.notNull(localCache);

Object rt = null;

if (this.cacheCluster) {

rt = mc.get(key);

} else {

Element element = null;

try {

element = localCache.get(key);

} catch (CacheException cacheException) {

throw new DataRetrievalFailureException(“Cache failure: “

+ cacheException.getMessage());

}

if(element != null)

rt = element.getValue();

}

return rt;

}

/**

* 判断是否存在

*

*/

public boolean exist(String key){

Assert.hasText(key);

Assert.notNull(localCache);

if (this.cacheCluster) {

return mc.keyExists(key);

}else{

return this.localCache.isKeyInCache(key);

}

}

private void init() {

if (this.cacheCluster) {

String[] serverlist = cacheServerList.split(“,”);

Integer[] weights = this.split(cacheServerWeights);

// initialize the pool for memcache servers

SockIOPool pool = SockIOPool.getInstance();

pool.setServers(serverlist);

pool.setWeights(weights);

pool.setInitConn(initialConnections);

pool.setMinConn(minSpareConnections);

pool.setMaxConn(maxSpareConnections);

pool.setMaxIdle(maxIdleTime);

pool.setMaxBusyTime(maxBusyTime);

pool.setMaintSleep(maintThreadSleep);

pool.setSocketTO(socketTimeOut);

pool.setSocketConnectTO(socketConnectTO);

pool.setNagle(nagleAlg);

pool.setHashingAlg(SockIOPool.NEW_COMPAT_HASH);

pool.initialize();

logger.info(“初始化memcachedpool!”);

}

}

private void destory() {

if (this.cacheCluster) {

SockIOPool.getInstance().shutDown();

}

}

}

然后实现函数的AOP拦截类,用来在函数执行前返回缓存内容

Java代码

public class CachingInterceptor implements MethodInterceptor {

private CacheService cacheService;

private String cacheKey;

public void setCacheKey(String cacheKey) {

this.cacheKey = cacheKey;

}

public void setCacheService(CacheService cacheService) {

this.cacheService = cacheService;

}

public Object invoke(MethodInvocation invocation) throws Throwable {

Object result = cacheService.get(cacheKey);

//如果函数返回结果不在Cache中,执行函数并将结果放入Cache

if (result == null) {

result = invocation.proceed();

cacheService.put(cacheKey,result);

}

return result;

}

}

public class CachingInterceptor implements MethodInterceptor {

private CacheService cacheService;

private String cacheKey;

public void setCacheKey(String cacheKey) {

this.cacheKey = cacheKey;

}

public void setCacheService(CacheService cacheService) {

this.cacheService = cacheService;

}

public Object invoke(MethodInvocation invocation) throws Throwable {

Object result = cacheService.get(cacheKey);

//如果函数返回结果不在Cache中,执行函数并将结果放入Cache

if (result == null) {

result = invocation.proceed();

cacheService.put(cacheKey,result);

}

return result;

}

}

Spring的AOP配置如下:

Java代码

aop:config proxy-target-class=”true”

aop:advisor

pointcut=”execution(* ×××.PoiService.getOne(..))”

advice-ref=”PoiServiceCachingAdvice” /

aop:config

bean id=”BasPoiServiceCachingAdvice”

class=”×××.core.cache.CachingInterceptor”

property name=”cacheKey” value=”PoiService” /

property name=”cacheService” ref=”cacheService” /

bean

转载

关于javamemcachedset和的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

本文来自投稿,不代表【】观点,发布者:【

本文地址: ,如若转载,请注明出处!

举报投诉邮箱:253000106@qq.com

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2024年3月29日 22:26:00
下一篇 2024年3月29日 22:33:14

相关推荐

  • 包含linuxiisaccess的词条

    毕业论文:linux系统的web服务器架设 1、我们以RedHat Linux 0系统为例,想要linuxconf在Web浏览器环境工作,必须进行以下设置: * 在gnome-linuxconf对话框中,打开“Config/Networking/Misc/Linuxconf network access”分支,选中“Enable netwoork acces…

    2024年5月23日
    4400
  • 包含黑客技术学习网址的词条

    信息安全技术专业的相关学习网站有哪些? 1、关于学习类的网站有掌门1对多贝、网易云课堂、慕课、传课、CSDN、我要自学网等等。 2、网络安全主要集中在大型城市,如北京上海广州深圳等,那里安全公司特别多,如360,天融信,奇安信等,所以学习网络安全建议选择这些城市。 3、入侵检测系统技术(IDS);加密&VPN技术;产品安全;安全管理。基础课程的主要内…

    2024年5月23日
    5000
  • 包含c语言对txt文件命名的词条

    如何在C语言编程里面修改源文件名字 如果你是在WINDOWS的话,简单了,随便用个编辑器,比如记事本,然后写c源程序,保存到你想要保存的位置。如果你在DOS下,可以用edit,写好以后,按alt键,选择文件菜单,然后保存。 用open打开文件,注意操作模式使用“修改”或者“添加” 用write或者fprintf向文件中写入你的内容。 用close关闭文件。 …

    2024年5月23日
    4800
  • 包含linux启动xinetd的词条

    简述linux进程的启动.终止的方式以及如何查看进程 查看启动的进程:可以使用以面命令来查看:01ps -ef |grep tomcat复制代码tomcat它是一个Java进程,所以查找Java进程也可查找出来。 ps -ef|grep java复制代码可以看到用户和进程编号,可以用kill 进程编号结束进程。 (1)手工启动 用户在输入端发出命令,直接启动…

    2024年5月23日
    4900
  • 包含linux内核二进制在内存分布的词条

    内存管理:一文读懂Linux内存组织结构及页面布局 (1)Linux虚拟内存实现机制 Linux虚拟内存的实现需要六种机制的支持:地址映射机制、内存分配回收机制、缓存和刷新机制、请求页机制、交换机制、内存共享机制。 Linux 内存管理是操作系统内核对物理内存的分配和管理。Linux 内存管理有两个基本任务:一是把可用的内存给程序使用,二是在物理内存不足时,…

    2024年5月23日
    4400
  • 包含Simcityjava的词条

    问一下各种程序的后缀 ,应用程序通常被分为两部分:图形用户接口(GUI)和引擎(Engien)。2,应用程序后缀名:(1)在DOS或Windows系统下其扩展名为*.exe或*.com;(2)在macosx下扩展名一般为*.app。 在windows操作系统下,可执行程序扩展名通常为.exe。全名executablefile,译作可执行文件,可移植可执行(P…

    2024年5月23日
    4600
  • 包含linuxnode后台运行的词条

    怎样使linux后台运行node服务指令 1、nohup node your_app.js & forever可以让我们做得更好,并且可以跨平台的在windows和Linux下都能运行。 2、安装指定版本的node.js(服务器基本软件的安装)你可以到nodejs org官网上面找到相对的tar.gz文件包,下载然后进行源码安装。 3、nodejs一…

    2024年5月23日
    3900
  • 包含hypervlinux集成服务的词条

    如何在Linux发行版中安装并启用Hyper-V集成服务 1、方法/步骤 在网上下载好linux系统的集成服务,并插入hyper-v磁盘中。用root 用户登录linux系统。linux系统自动载入cd rom 中。选择 install.sh,选择运行。运行中,重启电脑。 2、在Hyper-V控制台新建虚机,注意虚机的网卡先选择“旧版网络适配器”,主要是方便…

    2024年5月23日
    3900
  • 包含javajbtok的词条

    java的语法 1、Java的基本语法如下:大小写敏感:Java是大小写敏感的,这就意味着标识符Hello与hello是不同的。类名:对于所有的类来说,类名的首字母应该大写。 2、Java中区分大小写。类和接口名首字母必须大写,采用驼峰命名法,每一个名单词的首字母大写,例如:MyFirstJavaProgram;类名和源文件名必须一致。 3、关键字是电脑语言…

    2024年5月23日
    4000
  • 包含excelvbasaveas的词条

    如何用VBA新建一个新的excel表并将其保存在指定目录下 如下图所示,我想将桌面上第一章中的每个工作簿名称放置到工作表中。新建一个工作簿,将其命名为“第一章目录”,按alt+f11组合键,打开宏界面。 新建一个模块,将代码复制到到这个模块中,就会将当前工作表保存到thisworkbook目录下,并以txt格式来保存。 excel中使用vba来创建新的工作薄…

    2024年5月23日
    4900

发表回复

登录后才能评论



关注微信