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


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

    一、Memcached介绍

    (1)简介

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

    (2)特点

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

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

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

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

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

    (3)与Redis对比

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

    二、安装

    (1)下载

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

    在这里插入图片描述

    (2)解压

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

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O835iVp6-1665329325675)(img\image-20220226174957040.png)]

    (3)执行exe

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

    memcached.exe -d install
    
    • 1

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

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

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

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

    在这里插入图片描述

    ​ 也可以在任务管理器中进行服务状态的切换
    在这里插入图片描述

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

    三、Memcached整合SpringBoot

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

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

    (1)导入xmemcached的坐标

    <dependency>
        <groupId>com.googlecode.xmemcachedgroupId>
        <artifactId>xmemcachedartifactId>
        <version>2.4.7version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    (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;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在这里插入图片描述

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

    code实体类

    package com.test;
    
    import lombok.Data;
    
    @Data
    public class SMSCode {
        private String tele;
        private String code;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    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;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    code接口

    package com.test;
    
    public interface SMSCodeService {
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

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

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

    (4)定义配置属性

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

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

    @Component
    @ConfigurationProperties(prefix = "memcached")
    @Data
    public class XMemcachedProperties {
        private String servers;
        private int poolSize;
        private long opTimeout;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    b.定义memcached节点信息

    memcached:
      servers: localhost:11211
      poolSize: 10
      opTimeout: 3000
    
    • 1
    • 2
    • 3
    • 4

    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;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

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

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

  • 相关阅读:
    每天记录学习的新知识:AppInit
    【PHY】3GPP UE能力类别的变化
    Cys(Npys)-(Arg)₉,H2N-C(Npys)-RRRRRRRRR-OH
    在湖北考一个安全员c3住建厅安全员c证持证上岗
    Redis基础知识:redis有16个数据库、redis是单线程的!
    Windows11怎样投屏到电视上?
    数据库管理-第110期 Oracle Exadata 01(20231016)
    Android架构师学习必备学习宝典《Android架构开发手册》
    微信小程序 - WXML 模板语法 - 条件渲染
    linux gdb运行不下去的程序调试方法
  • 原文地址:https://blog.csdn.net/weixin_47343544/article/details/127236173