memcached的简单使用以及spring的集成

原文地址:https://blog.csdn.net/qiyongkang520/article/details/57083642

 

Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的hashmap。其守护进程(daemon )是用C写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信。 
下面,笔者分以下几个步骤来进行介绍:

一、安装以及启动

这里为了学习的方便,大家可以去下载一个windows版本的,地址如下:服务端下载地址,另外还有一个可视化工具memadmin,不过需要依赖php的环境,地址如下:可视化工具地址。 
停止和启动的命令如下: 
这里写图片描述

memcached.exe -d stop
memcached.exe -d start

二、java memcached客户端的使用

首先,maven依赖如下:

<!-- Memcached客户端 -->
    <dependency>
        <groupId>com.whalin</groupId>
        <artifactId>Memcached-Java-Client</artifactId>
        <version>3.0.2</version>
    </dependency>

 

memcached服务端默认的端口为11211,代码如下:

/**
 * Project Name:qyk_testJava
 * File Name:MemcachedClient.java
 * Package Name:com.qiyongkang.memcached
 * Date:2017年2月22日下午1:32:26
 * Copyright (c) 2017, Thinkive(http://www.thinkive.com/) All Rights Reserved.
 *
*/
 
package com.qiyongkang.memcached;
 
import com.whalin.MemCached.MemCachedClient;
import com.whalin.MemCached.SockIOPool;
 
/**
 * ClassName:MemcachedClient <br/>
 * Function: Memcached客户端. <br/>
 * Date:     2017年2月22日 下午1:32:26 <br/>
 * @author   qiyongkang
 * @version
 * @since    JDK 1.6
 * @see
 */
public class MemcachedClient {
    public static void main(String[] args) {
        // 初始化SockIOPool,管理memcached的连接池 
        String[] servers = { "127.0.0.1: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();
        // 将对象加入到memcached缓存 
        boolean success = memCachedClient.set("name", "qiyongkang");
        // 从memcached缓存中按key值取对象 
        String result = (String) memCachedClient.get("name");
        System.out.println(String.format("set:" + success));
        System.out.println(String.format("get:" + result));
    }
}
 

 

运行结果如下: 
这里写图片描述

三、spring中的集成

首先,我们把相关的配置属性放在属性文件memcached.properties中,如下:

#######################Memcached配置#######################  
#服务器地址  
memcached.server=127.0.0.1
memcached.port=11211
#初始化时对每个服务器建立的连接数目  
memcached.initConn=20  
#每个服务器建立最小的连接数  
memcached.minConn=10  
#每个服务器建立最大的连接数  
memcached.maxConn=50  
#自查线程周期进行工作,其每次休眠时间  
memcached.maintSleep=3000  
#Socket的参数,如果是true在写数据时不缓冲,立即发送出去  
memcached.nagle=false  
#Socket阻塞读取数据的超时时间  
memcached.socketTO=3000

 

然后,再来看看集成在spring中的memcachedContext.xml配置,如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd">
     <!-- properties config   -->  
    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  
      <property name="order" value="1"/>  
      <property name="ignoreUnresolvablePlaceholders" value="true"/>  
      <property name="locations">  
        <list> 
            <value>classpath:memcached.properties</value>  
        </list>  
      </property>  
    </bean>  
 
    <!-- Memcached配置 -->  
    <bean id="memcachedPool" class="com.whalin.MemCached.SockIOPool" 
        factory-method="getInstance" init-method="initialize" destroy-method="shutDown">  
        <property name="servers">  
            <list>  
                <value>${memcached.server}:${memcached.port}</value>  
            </list>  
        </property>  
        <property name="initConn">  
            <value>${memcached.initConn}</value>  
        </property>  
        <property name="minConn">  
            <value>${memcached.minConn}</value>  
        </property>  
        <property name="maxConn">  
            <value>${memcached.maxConn}</value>  
        </property>  
        <property name="maintSleep">  
            <value>${memcached.maintSleep}</value>  
        </property>  
        <property name="nagle">  
            <value>${memcached.nagle}</value>  
        </property>  
        <property name="socketTO">  
            <value>${memcached.socketTO}</value>  
        </property>  
    </bean>  
</beans>

 

然后,我们再封装一个MemcacheUtil工具类,如下:

/**
 * Project Name:qyk_testSpring
 * File Name:MemcacheUtil.java
 * Package Name:org.qiyongkang.spring.util
 * Date:2017年2月22日下午2:50:05
 * Copyright (c) 2017, Thinkive(http://www.thinkive.com/) All Rights Reserved.
 *
*/
 
package org.qiyongkang.spring.util;
 
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Date;
 
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
 
import com.whalin.MemCached.MemCachedClient;
 
/**
 * ClassName:MemcacheUtil <br/>
 * Function: memcache缓存工具类. <br/>
 * Date: 2017年2月22日 下午2:50:05 <br/>
 * 
 * @author qiyongkang
 * @version
 * @since JDK 1.6
 * @see
 */
public class MemcacheUtil {
    private static Logger logger = LogManager.getLogger(MemcacheUtil.class);
    private static String MEMCACHE_POOL_NAME = "default";
 
    /**
     * cachedClient.
     */
    private static MemCachedClient cachedClient;
    static {
        if (cachedClient == null) {
            cachedClient = new MemCachedClient(MEMCACHE_POOL_NAME);
        }
    }
 
    /**
     * 构造函数.
     */
    private MemcacheUtil() {
    }
 
    /**
     * 向缓存添加新的键值对。如果键已经存在,则之前的值将被替换.
     * 
     * @param key
     *            键
     * @param value
     *            值
     * @return boolean
     */
    public static boolean set(String key, Object value) {
        return setExp(key, value, null);
    }
 
    /**
     * 向缓存添加新的键值对。如果键已经存在,则之前的值将被替换.
     * 
     * @param key
     *            键
     * @param value
     *            值
     * @param expire
     *            过期时间 New Date(1000*10):十秒后过期
     * @return boolean
     */
    public static boolean set(String key, Object value, Date expire) {
        return setExp(key, value, expire);
    }
 
    /**
     * 向缓存添加新的键值对。如果键已经存在,则之前的值将被替换.
     * 
     * @param key
     *            键
     * @param value
     *            值
     * @param expire
     *            过期时间 New Date(1000*10):十秒后过期
     * @return boolean
     */
    private static boolean setExp(String key, Object value, Date expire) {
        boolean flag = false;
        try {
            flag = cachedClient.set(key, value, expire);
        } catch (Exception e) {
            logger.error("Memcached set方法报错,key值:" + key + "\r\n" + exceptionWrite(e));
        }
        return flag;
    }
 
    /**
     * 仅当缓存中不存在键时,add 命令才会向缓存中添加一个键值对.
     * 
     * @param key
     *            键
     * @param value
     *            值
     * @return boolean
     */
    public static boolean add(String key, Object value) {
        return addExp(key, value, null);
    }
 
    /**
     * 仅当缓存中不存在键时,add 命令才会向缓存中添加一个键值对.
     * 
     * @param key
     *            键
     * @param value
     *            值
     * @param expire
     *            过期时间 New Date(1000*10):十秒后过期
     * @return boolean
     */
    public static boolean add(String key, Object value, Date expire) {
        return addExp(key, value, expire);
    }
 
    /**
     * 仅当缓存中不存在键时,add 命令才会向缓存中添加一个键值对.
     * 
     * @param key
     *            键
     * @param value
     *            值
     * @param expire
     *            过期时间 New Date(1000*10):十秒后过期
     * @return boolean
     */
    private static boolean addExp(String key, Object value, Date expire) {
        boolean flag = false;
        try {
            flag = cachedClient.add(key, value, expire);
        } catch (Exception e) {
            logger.error("Memcached add方法报错,key值:" + key + "\r\n" + exceptionWrite(e));
        }
        return flag;
    }
 
    /**
     * 仅当键已经存在时,replace 命令才会替换缓存中的键.
     * 
     * @param key
     *            键
     * @param value
     *            值
     * @return boolean
     */
    public static boolean replace(String key, Object value) {
        return replaceExp(key, value, null);
    }
 
    /**
     * 仅当键已经存在时,replace 命令才会替换缓存中的键.
     * 
     * @param key
     *            键
     * @param value
     *            值
     * @param expire
     *            过期时间 New Date(1000*10):十秒后过期
     * @return boolean
     */
    public static boolean replace(String key, Object value, Date expire) {
        return replaceExp(key, value, expire);
    }
 
    /**
     * 仅当键已经存在时,replace 命令才会替换缓存中的键.
     * 
     * @param key
     *            键
     * @param value
     *            值
     * @param expire
     *            过期时间 New Date(1000*10):十秒后过期
     * @return boolean
     */
    private static boolean replaceExp(String key, Object value, Date expire) {
        boolean flag = false;
        try {
            flag = cachedClient.replace(key, value, expire);
        } catch (Exception e) {
            logger.error("Memcached replace方法报错,key值:" + key + "\r\n" + exceptionWrite(e));
        }
        return flag;
    }
 
    /**
     * get 命令用于检索与之前添加的键值对相关的值.
     * 
     * @param key
     *            键
     * @return boolean
     */
    public static Object get(String key) {
        Object obj = null;
        try {
            obj = cachedClient.get(key);
        } catch (Exception e) {
            logger.error("Memcached get方法报错,key值:" + key + "\r\n" + exceptionWrite(e));
        }
        return obj;
    }
 
    /**
     * 删除 memcached 中的任何现有值.
     * 
     * @param key
     *            键
     * @return boolean
     */
    public static boolean delete(String key) {
        return cachedClient.delete(key);
    }
 
    /**
     * 清理缓存中的所有键/值对.
     * 
     * @return boolean
     */
    public static boolean flashAll() {
        boolean flag = false;
        try {
            flag = cachedClient.flushAll();
        } catch (Exception e) {
            logger.error("Memcached flashAll方法报错\r\n" + exceptionWrite(e));
        }
        return flag;
    }
 
    /**
     * 返回异常栈信息,String类型.
     * 
     * @param e
     *            Exception
     * @return boolean
     */
    private static String exceptionWrite(Exception e) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        e.printStackTrace(pw);
        pw.flush();
        return sw.toString();
    }
}

 

这里需要说明一点,memcached连接池被创建的时候,可以传入一个poolName,如果没传就使用default,因此这个值要么为空,要么就是default,不要随便写,否则会报错的。这个大家可以去看下实例化memcached连接池的代码。 
最后,再来使用下,测试代码如下:

/**
 * Project Name:qyk_testSpring
 * File Name:MemcacheClientTest.java
 * Package Name:org.qiyongkang.spring.test
 * Date:2017年2月22日下午2:23:47
 * Copyright (c) 2017, Thinkive(http://www.thinkive.com/) All Rights Reserved.
 *
*/
 
package org.qiyongkang.spring.test;
 
import org.qiyongkang.spring.util.MemcacheUtil;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
/**
 * ClassName:MemcacheClientTest <br/>
 * Function: TODO ADD FUNCTION. <br/>
 * Reason: TODO ADD REASON. <br/>
 * Date:     2017年2月22日 下午2:23:47 <br/>
 * @author   qiyongkang
 * @version
 * @since    JDK 1.6
 * @see
 */
public class MemcacheClientTest {
    @SuppressWarnings("resource")
    public static void main(String[] args) {
        new ClassPathXmlApplicationContext("applicationContext.xml");
 
        //设置key
        boolean isSuccess = MemcacheUtil.set("name", "qiyongkang");
        System.out.println("是否成功:" + isSuccess);
        Object obj = MemcacheUtil.get("name");  
        System.out.println("获取name:" + obj); 
    }
}
 

运行结果如下: 
这里写图片描述
好了,就介绍到这儿了。另外关于memcached与spring的集成还有很多相关的东西,使用配置起来也比较方便,大家也可以去了解下。由于memcached缓存的数据全部是保存在内存中,所以一旦服务重启数据就全部遗失了,需要再次进行缓存。笔者平时用得比较多的是redis,关于两者之间的适用场景,大家可以去自行了解下~

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值