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
  • 1
  • 2

二、java memcached客户端的使用

首先,maven依赖如下:

<!-- Memcached客户端 -->
    <dependency>
        <groupId>com.whalin</groupId>
        <artifactId>Memcached-Java-Client</artifactId>
        <version>3.0.2</version>
    </dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

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));
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

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

三、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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

然后,再来看看集成在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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56

然后,我们再封装一个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();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256

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

扫描二维码关注公众号,回复: 1707718 查看本文章
/**
 * 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); 
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

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


猜你喜欢

转载自blog.csdn.net/cn_yaojin/article/details/80388887
今日推荐