SpringCache+Redis的整合(微服务)

news2024/11/18 13:34:17

缓存作用:

举个例子:在我们程序中,很多配置数据(例如一个商品信息、一个白名单、一个第三方客户的回调接口),这些数据存在我们的DB上,数据量比较少,但是程序访问很频繁,这种情况下,将数据放一份到我们的内存缓存中将大大提升我们系统的访问效率,因为减少了数据库访问,有可能减少了数据库建连时间、网络数据传输时间、数据库磁盘寻址时间……

总的来说,涉及查询场景都可以考虑使用缓存优化性能:1、查数据库2、读取文件3、网络访问,特别是调用第三方服务查询接口!

注意:并不是缓存设计的多,性能就一定好,对更新频繁的数据,不推荐缓存,保证数据一致性是缓存的前提!

一致性解释:缓存数据和数据库数据一致,避免脏(错误)数据!

第一步:添加相关依赖

在这里插入图片描述

<!-- 缓存依赖 -->
        <!--spring-cache-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>
        <!--redis依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!-- redis连接池-->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>

第二步:在公共模块的resources目录中添加application-cache .yml

在这里插入图片描述

spring:
  cache:
    type: redis  #缓存设置为Redis类型
  redis: # 设置Redis连接信息
    host: 1.15.122.194 #存放缓存的服务器id
    port: 6379 # 端口号
    jedis: # 设置Redis连接池
      pool:
        max-wait: 2000ms
        min-idle: 2 #最小空闲数
        max-idle: 8 #最大空闲数
        max-active: 10 #最大连接数

第三步:编写缓存配置类(这个只是单纯的配置类,并没有使用@Configuration注解生效,需要其他配置类集成它,添加@Configuration注解才可以生效生效)

在这里插入图片描述

/**
 * @author: 
 * @date: 2022/12/20
 * @description: 缓存配置类 放置配置的方法,子模板继承和复用
 */
public class CacheConfiguration {
    //配置缓存manager
    @Bean
    @Primary  //同类型,多个bean,默认生效! 默认缓存时间1小时!  可以选择!
    public RedisCacheManager cacheManagerHour(RedisConnectionFactory redisConnectionFactory){

        RedisCacheConfiguration instanceConfig = instanceConfig(1 * 3600L);//缓存时间1小时

        //构建缓存对象
        return RedisCacheManager.builder(redisConnectionFactory)
                .cacheDefaults(instanceConfig)
                .transactionAware()
                .build();
    }

    //缓存一天配置
    @Bean
    public RedisCacheManager cacheManagerDay(RedisConnectionFactory redisConnectionFactory){

        RedisCacheConfiguration instanceConfig = instanceConfig(24 * 3600L);//缓存时间1小时

        //构建缓存对象
        return RedisCacheManager.builder(redisConnectionFactory)
                .cacheDefaults(instanceConfig)
                .transactionAware()
                .build();
    }


    /**
     * 实例化具体的缓存配置!
     *    设置缓存方式JSON
     *    设置缓存时间 单位秒
     * @param ttl
     * @return
     */
    private RedisCacheConfiguration instanceConfig(Long ttl){

        //设置jackson序列化工具
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer
                = new Jackson2JsonRedisSerializer<Object>(Object.class);

        //常见jackson的对象映射器,并设置一些基本属性
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        objectMapper.registerModule(new JavaTimeModule());
        objectMapper.configure(MapperFeature.USE_ANNOTATIONS,false);
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,
                ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);

        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

        return RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofSeconds(ttl)) //设置缓存时间
                .disableCachingNullValues()
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer));
    }

}

第四步:在服务消费者pom.xml中添加公共模块依赖,以此来使用缓存

<dependency>
   <artifactId>store-commons</artifactId>
   <groupId>com.xin</groupId>
   <version>1.0-SNAPSHOT</version>
</dependency>

第五步:在application.yml文件中激活缓存

在这里插入图片描述

spring:
  # 连接池配置
  datasource:
    url: jdbc:mysql://localhost:3306/store_admin?useSSL=false
    username: root
    password: root
    driver-class-name: com.mysql.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
  profiles:
    active: cache,mq # 激活mq(消息队列),#激活store-common模块的缓存cache(缓存)
  thymeleaf:
    cache: true  #开启缓存
    check-template: true  #检查模板是否存在
    check-template-location: true # 检查模板位置正确性 默认查找 resources templates文件夹内
    servlet:
      content-type: text/html # 直接嵌入到html文件中
    enabled: true
    encoding: UTF-8

mybatis-plus:
  mapper-locations: classpath:mappers/*.xml
  configuration:
    map-underscore-to-camel-case: true
    auto-mapping-behavior: full
    lazy-loading-enabled: true
    aggressive-lazy-loading: false
  type-aliases-package: com.xin.pojo #设置别名a
ribbon:
  ReadTimeout: 60000
  ConnectTimeout: 60000
  eager-load:
    enabled: true #开启饥饿加载提升第一次访问速度
    clients:
      - admin-service #指定开启服务
feign:
  httpclient:
    enabled: true  # 开启httpClient开关,启动连接池,提升feign连接效率!
    max-connections: 200  #最大连接数量
    max-connections-per-route: 50  #单路径最大连接数
  client: #默认 1秒
    default: # 设置连接超时时间
      ConnectTimeOut: 10000
      ReadTimeOut: 10000 #设置读取数据超时时间

server:
  servlet:
    context-path: /admin #访问的根路径

#OSS配置
aliyun:
  oss:
    file:
      # 控制台 - oss - 点击对应桶 - 概览 - 地域节点
      endpoint: oss-cn-beijing.aliyuncs.com
      keyid: LTAI5t82cN3TfofxJywKvoj5
      keysecret: 7cPhJQBMNewuqXXnUiEjpj1l8YeONo
      bucketname: store-b2c

第六步:在启动类上添加@EnableCaching,开启缓存

在这里插入图片描述

第七步:创建配置类,集成公共模块中的CacheConfiguration缓存配置类

在这里插入图片描述

第八步:在service层中使用缓存

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

SpringBoot实现Redis缓存(SpringCache+Redis的整合)

补充:

@Cacheable

位置:添加到方法和类上
作用:调用方法,查询是否有缓存,有直接走缓存,没有走方法,将方法的返回值进行缓存!
参数:
     value = String{} 配置缓存的 配置缓存‘分区’,相当于缓存的标示!
     key   = String   配置缓存的 ‘分区’下的具体表示,此处支持SpringEL表达式,动态命名
     cacheManager = String 选择配置类中的缓存配置对象beanname,不选走默认!
     condition = String 注解生效条件, 支持SpringEl表达式 例如: "#result != null"
                            结果不为null,进行缓存!
例如:
    @Cacheable(value = "product",key = "#root.methodName+" +
                                        "'-'+#productParamInteger.categoryID+" +
                                        "'-'+#productParamInteger.currentPage+" +
                                        "'-'+#productParamInteger.pageSize",cacheManager = "cacheManagerbean")
                                        
SpringEL表达式简单了解:
    
    #开头
    #root.method 被调用的方法
    #root.methodName 被调用的方法名称
    #root.target 调用方法的对象
    #root.args  方法的参数对象数组 支持[index]获取具体参数
    #result 方法执行后的结果
    #形参名  直接获取行参数名称 支持ognl向下继续读取
 
注意:
    缓存也分为curd
    所以,设计缓存value和key的时候,多思考,后期还需要进行删除和替换动作!   

@CachePut

位置:添加到方法和类上
作用:不影响方法使用,将方法的返回值,进行指定的key更新,通常添加到修改方法上!
参数:
     value = String{} 配置缓存的 配置缓存‘分区’,相当于缓存的标示!
     key   = String   配置缓存的 ‘分区’下的具体表示,此处支持SpringEL表达式,动态命名
     cacheManager = String 选择配置类中的缓存配置对象beanname,不选走默认!
     condition = String 注解生效条件, 支持SpringEl表达式 例如: "#result != null"
                            结果不为null,进行更新!
例如:
    @CachePut(key = "#id", condition = "#result != null"),

@CacheEvict

位置:添加到方法和类上
作用:不影响方法使用,将方法的返回值,进行指定的key失效,通常添加到删除方法上!
参数:
     value = String{} 配置缓存的 配置缓存‘分区’,相当于缓存的标示!
     key   = String   配置缓存的 ‘分区’下的具体表示,此处支持SpringEL表达式,动态命名
     cacheManager = String 选择配置类中的缓存配置对象beanname,不选走默认!
     condition = String 注解生效条件, 支持SpringEl表达式 例如: "#result != null"
                            结果不为null,进行失效!
例如:
   //单一失效
   @CacheEvict(value = "student", key = "'saveCache01'")
   //allEntries = true 删除分区所有的数据
   @CacheEvict(value = "list.product",allEntries = true)
   //多点失效
   @Caching(evict = {
            @CacheEvict(value = "student", key = "'saveCache01'"),
            @CacheEvict(value = "student", key = "'saveCache02'")
    }

@Caching

位置:添加方法和类上
作用:多包涵注解,可以包含上面三个注解,用于复杂的缓存策略!
参数:
    Cacheable [] cacheable 配置多个缓存
    CachePut []  put 配置多个更新
    CacheEvict [] evict() 配置多个缓存

例如:
   订单模块
   订单支付,需要更新订单缓存,还要清空热门商品缓存!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/112905.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Prometheus(十一)Grafana告警

主要概念和特点 关键概念或特征含义Data sources for Alerting 告警的数据源配置从哪里查询到告警信息数据Provisioning for Alerting 告警的配置使用文件等方式配置警报资源&#xff0c;已经管理警报资源Scheduler 调度器评估告警规则&#xff0c;将其视为定期对数据源运行查…

ubuntu虚拟机修改静态ip

我的是&#xff1a;ubuntu 20.04&#xff0c;所以 第一步 sudo vi /etc/netplan/01-network-manager-all.yaml第二步 gateway4已经弃用了&#xff0c;换成下面的&#xff1a; network:version: 2renderer: NetworkManagerethernets:ens33:addresses: [192.168.125.132/24]r…

内核比较: 2.6 内核中改进了内存管理

随着 Linux 内核的发展和成熟&#xff0c;更多的用户期待着 Linux 可以运行非常大的系统来处理科学分析应用程序或者海量数据库。这些企业级的应用程序通常需要大量的内存才能好好运行。2.4 Linux 内核有识别相当大数量的内存的功能&#xff0c;但是 2.5 内核发生了很多改变&am…

docker高级篇第三章-dockerfile案例之制作自己的centos镜像

在上一篇文章中《Dockerfile介绍及常用保留指令》,我们介绍了Dockerfile是什么以及Dockerfile常用的保留字段。熟悉了这些之后,有没有想自己动手写一个Dockerfile呢?本文咱们就实战自己Dockerfile。 案例需求: 我们以远程仓库的centos为模板,制作出代用vim\ifconfig\jav…

Qt实现表格树控件-自绘树节点虚线

一、开心一刻 一程序员第一次上女朋友家她妈板着脸问 &#xff1a;你想娶我女儿&#xff0c;有多少存款&#xff1f; 程序员低了下头&#xff1a;五百&#xff01; 她妈更鄙视了&#xff1a;才五百块&#xff0c;买个厕所都不够&#xff01; 程序员忙说&#xff1a;不是人民币&…

Android混淆技术综述

1. 引入 大量的恶意软件都使用了混淆技术来逃检测。查了下Android混淆技术&#xff0c;看了如下两篇资料&#xff1a; Understanding Android Obfuscation Techniques: A Large-Scale Investigation in the Wildhttps://github.com/ClaudiuGeorgiu/Obfuscapk 对Android的混淆…

logging日志管理

1.日志作用 不管是在项目开发还是测试过程中&#xff0c;项目运行一旦出现问题日志信息就非常重要了。日志是定位问题的重要手段&#xff0c;就像侦探人员要根据现场留下的线索来推断案情。 2.日志级别 脚本运行会有很多的情况&#xff0c;比如调试信息、报错异常信息等。日…

渣土车空车未盖盖识别系统 OpenCv

渣土车空车未盖盖识别系统通过OpenCvyolo网络模型实时检测路过的渣土车情况&#xff0c;发现空车未盖盖立即进行抓拍回传。OpenCV基于C实现&#xff0c;同时提供python, Ruby, Matlab等语言的接口。OpenCV-Python是OpenCV的Python API&#xff0c;结合了OpenCV CAPI和Python语言…

Android开发中的线程池使用

一、前言 既然Android中已经有了线程的概念&#xff0c;那么为什么需要使用线程池呢&#xff1f;我们从两个方面给出使用线程池的原因。 首先线程的新建和销毁都是存在性能上的消耗的&#xff0c;如果一个时间段有大量的网络请求&#xff0c;那么就需要多个线程的创建与销毁&am…

NSGA and NSGA-II

目录1 NSGA1.1 传统多目标优化方法1.2 多目标转为单目标的缺点1.3 权重向量距离说明1.4 NSGA方法1.4.1 流程1.4.2 关键步骤1.5 注意2 NSGA-II2.1 NSGA的缺点2.2 NSGA-II在NSGA上的变动2.3 NSGA-II流程1 NSGA 1.1 传统多目标优化方法 使用权重向量&#xff0c;将多目标问题转化…

Java入门练习题及其答案第一弹

Java入门练习题及其答案第一弹 文章目录Java入门练习题及其答案第一弹素数打印乘法口诀表最大公约数水仙花数二进制中1的个数二进制奇偶数位素数打印 只能被1和自己整除 import java.util.Scanner;public static void main(String[] args) {Scanner scanner new Scanner(Sys…

UI自动化测试-第一个测试脚本

前提 我们在进行UI自动化测试时&#xff0c;一般采用javaselenium或者pythonselenium的方式。由于python比较简单&#xff0c;上手快&#xff0c;因此建议大家采用pythonselenium的方式来进行UI自动化。 1、安装pycharm PyCharm是一种Python IDE&#xff08;Integrated Deve…

【OpenCV-Python】教程:7-5 理解SVM

OpenCV Python SVM 学习 【目标】 直观理解 SVM 【理论】 线性可分 下图有两种类型的数据&#xff0c;红色和蓝色。在kNN中&#xff0c;对于一个测试数据&#xff0c;我们用来测量它与所有训练样本的距离&#xff0c;并取距离最小的一个。测量所有的距离需要大量的时间&am…

计算距离春节还有多长时间

你知道距离春节&#xff0c;还剩下多少时间吗&#xff1f; 或许你已经在默默心算了。 可是&#xff0c;如果我想要精确一点的结果&#xff0c;比如精确到多少分钟、多少秒呢&#xff1f; 要怎么计算呢&#xff1f; 这里可以使用Python进行计算。 首先&#xff0c;需要导入…

Opencv项目实战:18 人体姿态检测

目录 0、项目介绍 1、效果展示 2、项目搭建 3、项目代码讲解与介绍 Basics.py PoseModule.py Example.py 人体姿态图​编辑 4、项目资源 5、项目总结 0、项目介绍 mediapipe中有人体姿态检测的功能&#xff0c;今天我们就将实现最最基础的人体姿态估计项目&#xff0c;它…

【C++】深拷贝和浅拷贝

目录 浅拷贝 深拷贝 字符串的构造 例有两个类的深拷贝&#xff1a; 浅拷贝 在类中&#xff0c;若我们不写拷贝构造函数&#xff0c;则程序会提供一个默认的拷贝构造函数&#xff0c;该函数为浅拷贝。 //默认拷贝构造 ---浅拷贝--值复制 类名(const 类名& 形参名) {成…

【实时数仓】DWS层之商品主题计算、地区主题表(FlinkSQL)

文章目录一 DWS层-商品主题计算1 把JSON字符串数据流转换为统一数据对象的数据流&#xff08;1&#xff09;转换订单宽表流数据&#xff08;2&#xff09;转换支付宽表流数据2 把统一的数据结构流合并为一个流&#xff08;1&#xff09;代码&#xff08;2&#xff09;测试3 设定…

216. 组合总和 III

216. 组合总和 III 找出所有相加之和为 n 的 k 个数的组合&#xff0c;且满足下列条件&#xff1a; 只使用数字1到9每个数字 最多使用一次 返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次&#xff0c;组合可以以任何顺序返回。 示例 1: 输入: k 3, n 7 输…

3.2 Static Terrestrial Laser Scanners 静态地基激光扫描仪

本章节介绍的静态地基激光扫描系统指的是那些在一个固定位置的位置上对周边场景地物特征进行扫描的设备。该类型设备的扫描测量机制是&#xff0c;通过激光测距仪进行斜距测量&#xff0c;与此同时通过水平和竖直两个方向上同步运动的角度编码器来记录角度变化值&#xff08;如…

编译原理——正规式、NFA构造DFA

一、DFA和NFA的区别 NFA&#xff1a;非确定有限自动机 DFA&#xff1a;确定有限自动机 NFA在同一状态&#xff0c;可以有多条出边&#xff0c;DFA在同一状态&#xff0c;只能有一条出边&#xff1b; NFA的初态可以具有多个&#xff0c;DFA的初态是唯一的&#xff1b; 比如这个…