Springboot 整合 memcache

Memcache介绍


  首先来说Memcache是一个开源高性能的分布式内存对象key-value缓存系统,用于加速动态的Web应用,从而减轻数据库的负载能力,在工作场景中很多人把它当做一个内存式的数据库在使用。那么内存式到底是什么呢?我们都知道,在计算机主要靠CPU来进行计算,内存用来存储CPU操作的数据。在计算机硬件中还有一个叫做硬盘的东西。那么这三者之间是怎么交互的。首先要知道计算机内存式有限的,这个是不可否认的,其次CPU的计算速度与内存以及外部存储之间是存在一定的差距的,所以就使用了一种高速缓存Cache的技术。来匹配内存与CPU之间的速度不匹配的问题。也就是说在计算机中能跟内存挂钩的都是速度比较搞的。Memcache被称为是内存式的缓存,那么它的效率一定是毋庸置疑。

  它可以应对任意多个连接,使用非阻塞的网络IO,由于它的工作机制就是跟上面说的一样是直接操作内存,在内存中开辟的空间,然后建立Hash表,并且有Memcache自己来管理这些Hash表,这样的方式来进行缓存操作,再加上非阻塞的IO。执行的效率上要比一般的缓冲设计结构更高效。

Memcache 特点


协议简单
  Memcache在服务端和客户端之间的通信中采用的是最为简单的文本协议,可以通过Telnet就可以在Memcache上存取数据。

基于Libevent的事件处理机制
  Libevent是一套跨平台的事件处理接口的封装。首先要知道在不同操作系统中对于事件的操作是不一样的,例如在不同的Linux版本中操作IO事件有poll、epoll。在Windows中的select。当然在低版本的Linux中也有使用select的。那么这些在不同平台上的IO事件处理,在Memcache中都得到了解决,使用Libevent进行网络并发连接的处理,能够保证在高并发的情况下,任然可以保持快速响应的能力。

内置的内存存储方式
  之前提到的Memcache中保存的数据都存储在Memcache内置的内存空间中,由于数据存储在内存中,所以当出现宕机或者是出现重启的时候就会导致内存中的数据丢失,都知道内存中的数据并不是持久化存储的。Memcache LRU(Least Recently Used)算法自动删除不使用的缓存,不过这个功能是可以进行配置的,Memcache通过启动“-M”参数可以禁止LRU,当是为了高效实用建议不要禁用。

不适用场景列举


缓存对象不能大于1MB,毕竟操作的是内存太大的话会导致内存消耗加速
key 的长度大于250字符,还是上面的原因
Memcache 未提供任何的安全策略,也就是说有些数据可以这里获取
不支持持久化,因为操作的是内存。

Memcache 安装

linux可参考材料教程,十分详细:https://www.runoob.com/memcached/memcached-install.html

windows:https://www.runoob.com/memcached/window-install-memcached.html

连接操作:https://www.runoob.com/memcached/memcached-connection.html

memcache 整合springboot 

环境准备好后,我们开始来整合springboot ;以下整合的是这两种客户端

  • SpyMemcached 停止更新
  • XMemcached 主流

方式一:整合SpyMemcached

1、导入mvn坐标

 <!--memcache SpyMemcached -->        
        <dependency>
            <groupId>net.spy</groupId>
            <artifactId>spymemcached</artifactId>
            <version>2.12.2</version>
        </dependency>

2、添加配置文件

通过@ConfigurationProperties(prefix = "springboot.memcache") 读取配置文件中以springboot.memcache为前缀的信息

package com.asiainfo.group.index.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * @Author panghl
 * @Date 2021/7/4 17:05
 * @Description memcache 读取配置信息
 **/
@Component
@ConfigurationProperties(prefix = "springboot.memcache")
public class MemcacheSource {
    private String ip;
    private int port;

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }
}

编写配置类,连接memcached 将MemcachedClient 实例 注入ioc容器

package com.asiainfo.group.index.config;

import net.spy.memcached.MemcachedClient;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.net.InetSocketAddress;

/**
 * @Author panghl
 * @Date 2021/7/4 17:08
 * @Description TODO
 **/
@Component
public class MemcacheRunner implements CommandLineRunner {

    @Resource
    private MemcacheSource memcacheSource;

    private MemcachedClient client = null;

    @Override
    public void run(String... args) throws Exception {
        try {
            client = new MemcachedClient(new InetSocketAddress(memcacheSource.getIp(),memcacheSource.getPort()));

        }catch (IOException e){
            e.printStackTrace();
        }
    }

    public MemcachedClient getClient(){
        return client;
    }


}

3、编写配置文件

springboot:
  memcache:
    ip: 47.108.14.XXX //memcached 的ip 
    port: 11211  //端口

4、编写测试类

@Resource
private MemcacheRunner memcacheRunner;

    @GetMapping("/set")
    public BaseResponse set(String key ,String value) {
        memcacheRunner.getClient().set(key,10,value);
        return BaseResponse.sendResponse(RetCode.SUCCESS,value);
    }


    @GetMapping("/get")
    public BaseResponse get(String key) {
        String val = (String)memcacheRunner.getClient().get(key);
            if (val ==null){
                return BaseResponse.sendResponse(RetCode.SUCCESS,"缓存到期了");
            }

        return BaseResponse.sendResponse(RetCode.SUCCESS,val);
    }

方式二:整合XMemcached

XMemcached介绍
  是使用最为广泛的Memcache Java客户端,是一个全新的 Java Memcache Client。Memcache 通过它自定义协议与客户端交互,而XMemcached就是它的Java客户端实现,相比较于其他客户端来说XMemcached 的优点如下

XMemcached主要特性

   XMemcached 支持设置连接池、宕机报警、使用二进制文件、一致性Hash、进行数据压缩等操作,总结下来有以下一些点

  • 性能优势,使用的NIO
  • 协议支持广泛
  • 支持客户端分布,提供了一致性Hash 实现
  • 允许设置节点权重,XMemcached允许通过设置节点的权重来调节Memcached的负载,设置的权重越高,该Memcached节点存储的数据就越多,所要承受的负载越大
  • 动态的增删节点,Memcached允许通过JMX或者代码编程来实现节点的动态的添加或者删除操作。方便扩展或者替换节点。
  • XMemcached 通过 JMX 暴露的一些接口,支持Client本身的监控和调整,允许动态设置调优参数、查看统计数据、动态增删节点等;
  • 支持链接池操作。
  • 可扩展性强,XMemcached是基于Java NIO框架 Yanf4j 来实现的,所以在结构上相对清晰,分层明确。

1、导入mvn坐标

    <!--        XMemcached-->
        <dependency>
            <groupId>com.googlecode.xmemcached</groupId>
            <artifactId>xmemcached</artifactId>
            <version>2.4.5</version>
        </dependency>

        <dependency>
            <groupId>commons-pool</groupId>
            <artifactId>commons-pool</artifactId>
            <version>1.5.6</version>
        </dependency>

2、添加配置文件

通过@ConfigurationProperties(prefix = "memcached") 读取配置文件中以springboot.memcache为前缀的信息

package com.asiainfo.group.index.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * @Author panghl
 * @Date 2021/7/4 17:08
 * @Description 读取配置信息
 **/
@Component
@ConfigurationProperties(prefix = "memcached")
public class XMemcachedProperties {
    private String servers;
    private int poolSize;
    private long opTimeout;

    public String getServers() {
        return servers;
    }

    public void setServers(String servers) {
        this.servers = servers;
    }

    public int getPoolSize() {
        return poolSize;
    }

    public void setPoolSize(int poolSize) {
        this.poolSize = poolSize;
    }

    public long getOpTimeout() {
        return opTimeout;
    }

    public void setOpTimeout(long opTimeout) {
        this.opTimeout = opTimeout;
    }
}

编写配置类,连接memcached 将MemcachedClient 实例 注入ioc容器

package com.asiainfo.group.index.config;

import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.MemcachedClientBuilder;
import net.rubyeye.xmemcached.XMemcachedClientBuilder;
import net.rubyeye.xmemcached.utils.AddrUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import java.io.IOException;

/**
 * @Author panghl
 * @Date 2021/7/4 17:31
 * @Description MemcachedBuilder
 **/
@Configuration
public class MemcachedBuilder {
    protected static Logger logger = LoggerFactory.getLogger(MemcachedBuilder.class);

    @Resource
    private XMemcachedProperties xMemcachedProperties;

    @Bean
    public MemcachedClient getMemcachedClinet(){
        MemcachedClient memcachedClient = null;
        try {
            MemcachedClientBuilder builder = new XMemcachedClientBuilder(AddrUtil.getAddresses(xMemcachedProperties.getServers()));
            builder.setConnectionPoolSize(xMemcachedProperties.getPoolSize());
            builder.setOpTimeout(xMemcachedProperties.getOpTimeout());
            memcachedClient = builder.build();
        }catch (IOException e){
            logger.error("init MemcachedClient failed"+e);
        }
        return memcachedClient;
    }
}

3、编写配置信息

memcached:
  servers: 47.108.14.XXX:11211  //ip:端口
  poolSize: 10        //连接池大小
  opTimeout: 6000    //超时时间

4、编写测试类

@Resource
private MemcachedClient memcachedClient;


    @GetMapping("/set")
    public BaseResponse set(String key ,String value) {
        try {
            memcachedClient.set(key,10,value);
        } catch (TimeoutException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (MemcachedException e) {
            e.printStackTrace();
        }
        return BaseResponse.sendResponse(RetCode.SUCCESS,value);
    }


    @GetMapping("/get")
    public BaseResponse get(String key) {
        String val = null;
        try {
            val = (String)memcachedClient.get(key);
            if (val ==null){
                return BaseResponse.sendResponse(RetCode.SUCCESS,"缓存到期了");
            }
        } catch (TimeoutException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (MemcachedException e) {
            e.printStackTrace();
        }
        return BaseResponse.sendResponse(RetCode.SUCCESS,val);
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值