《SpringBoot篇》18.SpringBoot整合Memcached缓存超详细教程

时间:2022-10-16 10:52:53
陈老老老板
说明:工作了,学习一些新的技术栈和工作中遇到的问题,边学习边总结,各位一起加油。需要注意的地方都标红了,还有资源的分享. 一起加油。
本文是介绍Memcached与SpringBoot整合

一、Memcached介绍

(1)简介

整合之前先大致了解一下Memcached,是一个​ 免费开源的、高性能的、具有分布式内存对象的缓存系统,它通过减轻数据库负载加速动态Web应用;(可以比作一个大内存条,要比访问数据库快得多)

(2)特点

1.简单key/value存储:服务器不关心数据本身的意义及结构,只要是可序列化数据即可。存储项由“键、过期时间、可选的标志及数据”四个部分组成;

2.功能的实现一半依赖于客户端,一半基于服务器端:客户负责发送存储项至服务器端、从服务端获取数据以及无法连接至服务器时采用相应的动作;服务端负责接收、存储数据,并负责数据项的超时过期;

3.各服务器间彼此无视:不在服务器间进行数据同步;

4.O(1)的执行效率;

5.清理超期数据:默认情况下,Memcached是一个LRU缓存,同时,它按事先预订的时长清理超期数据;但事实上,memcached不会删除任何已缓存数据,只是在其过期之后不再为客户所见;而且,memcached也不会真正按期限清理缓存,而仅是当get命令到达时检查其时长。

(3)与Redis对比

对比参数 Redis Memcached
支持的数据存储类型 String、list、set、zset、hash 文本型、二进制型
查询操作 1.批量操作
2.支持事务
3.每个类型CRUD不同
CRUD和少量其他命令
网络模型 单线程IO复用模型 多线程非阻塞IO模型
附加功能 1.发布/订阅模式
2.主从分区
3.序列号支持
4.脚本支持
多线程服务支持
持久化支持 RDB、AOF 不支持
事件库 AeEvent LibEvent

二、安装

(1)下载

​ windows版安装包下载地址:https://www.runoob.com/memcached/window-install-memcached.html
也可以在官网看更多关于Memcached的细节知识。
注:点击链接是无法下载的,复制链接,粘贴到搜索栏就能下载了

《SpringBoot篇》18.SpringBoot整合Memcached缓存超详细教程

(2)解压

​ 下载的安装包是解压缩就能使用的zip文件,解压缩完毕后会得到如下文件(可以说是超级轻量了)。

《SpringBoot篇》18.SpringBoot整合Memcached缓存超详细教程

(3)执行exe

执行安装服务的命令即可,如下:

memcached.exe -d install

​ 可执行文件只有一个memcached.exe,使用该文件可以将memcached作为系统服务启动,执行此文件时会出现报错信息,如下:

《SpringBoot篇》18.SpringBoot整合Memcached缓存超详细教程

注:此处出现问题的原因是注册系统服务时需要使用管理员权限,当前账号权限不足导致安装服务失败,切换管理员账号权限启动命令行

《SpringBoot篇》18.SpringBoot整合Memcached缓存超详细教程

​ 服务安装完毕后可以使用命令启动和停止服务,如下:

memcached.exe -d start		# 启动服务
memcached.exe -d stop		# 停止服务

《SpringBoot篇》18.SpringBoot整合Memcached缓存超详细教程

​ 也可以在任务管理器中进行服务状态的切换
《SpringBoot篇》18.SpringBoot整合Memcached缓存超详细教程

注:点击任务管理器边框,直接输入mem就可以搜索到。

三、Memcached整合SpringBoot

说明:SpringBoot并没有收录memcached为缓存解决方案,因此使用memcached需要通过手工硬编码的方式来使用。

​memcached目前提供有三种客户端技术
Memcached Client for Java、
SpyMemcached、
Xmemcached,
其中性能指标各方面最好的客户端是Xmemcached,本次整合就使用Xmemcached。

(1)导入xmemcached的坐标

<dependency>
    <groupId>com.googlecode.xmemcached</groupId>
    <artifactId>xmemcached</artifactId>
    <version>2.4.7</version>
</dependency>

《SpringBoot篇》18.SpringBoot整合Memcached缓存超详细教程

(2)配置memcached,制作memcached的配置类

说明:memcached默认对外服务端口11211。

package com.test;

import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.MemcachedClientBuilder;
import net.rubyeye.xmemcached.XMemcachedClientBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;

@Configuration
public class XMemcachedConfig {
    @Bean
    public MemcachedClient getMemcachedClient() throws IOException {
        MemcachedClientBuilder memcachedClientBuilder = new XMemcachedClientBuilder("localhost:11211");
        MemcachedClient memcachedClient = memcachedClientBuilder.build();
        return memcachedClient;
    }
}

《SpringBoot篇》18.SpringBoot整合Memcached缓存超详细教程

(3)使用xmemcached客户端操作缓存,注入MemcachedClient对象

code实体类

package com.test;

import lombok.Data;

@Data
public class SMSCode {
    private String tele;
    private String code;
}

code工具类

@Component
public class CodeUtils {
    private String [] patch = {"000000","00000","0000","000","00","0",""};

    public String generator(String tele){
        int hash = tele.hashCode();
        int encryption = 20206666;
        long result = hash ^ encryption;
        long nowTime = System.currentTimeMillis();
        result = result ^ nowTime;
        long code = result % 1000000;
        code = code < 0 ? -code : code;
        String codeStr = code + "";
        int len = codeStr.length();
        return patch[len] + codeStr;
    }

    @Cacheable(value = "smsCode",key="#tele")
    public String get(String tele){
        return null;
    }
}

code接口

package com.test;

public interface SMSCodeService {
}

code实现类

@Service
public class SMSCodeServiceImpl implements SMSCodeService {
    @Autowired
    private CodeUtils codeUtils;
    @Autowired
    private MemcachedClient memcachedClient;

    public String sendCodeToSMS(String tele) {
        String code = codeUtils.generator(tele);
        try {
            memcachedClient.set(tele,10,code);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return code;
    }

    public boolean checkCode(SMSCode smsCode) {
        String code = null;
        try {
            code = memcachedClient.get(smsCode.getTele()).toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return smsCode.getCode().equals(code);
    }
}

说明:设置值到缓存中使用set操作,取值使用get操作,其实更符合我们开发者的习惯。

(4)定义配置属性

a.定义配置类,加载必要的配置属性

读取配置文件中memcached节点信息

@Component
@ConfigurationProperties(prefix = "memcached")
@Data
public class XMemcachedProperties {
    private String servers;
    private int poolSize;
    private long opTimeout;
}

b.定义memcached节点信息

memcached:
  servers: localhost:11211
  poolSize: 10
  opTimeout: 3000

c.在memcached配置类中加载信息

@Configuration
public class XMemcachedConfig {
    @Autowired
    private XMemcachedProperties props;
    @Bean
    public MemcachedClient getMemcachedClient() throws IOException {
        MemcachedClientBuilder memcachedClientBuilder = new XMemcachedClientBuilder(props.getServers());
        memcachedClientBuilder.setConnectionPoolSize(props.getPoolSize());
        memcachedClientBuilder.setOpTimeout(props.getOpTimeout());
        MemcachedClient memcachedClient = memcachedClientBuilder.build();
        return memcachedClient;
    }
}

总结:缓存是为了减少对数据库的压力,之后会有各种缓存整合的博客。希望对您有帮助,感谢阅读

结束语:裸体一旦成为艺术,便是最圣洁的。道德一旦沦为虚伪,便是最下流的。
勇敢去做你认为正确的事,不要被世俗的流言蜚语所困扰。