SpringBoot使用本地缓存——Caffeine

SpringBoot使用本地缓存——Caffeine

缓存,想必大家都用过,将常用的数据存储在缓存上能在一定程度上提升数据存取的速度。这正是局部性原理的应用。之前用的缓存大多是分布式的,比如Redis。使用Redis作为缓存虽然是大多数系统的选择,但是需要另起服务,且会增加一定的耗时在数据传输上。对于一些小型应用,用Redis就有点大材小用了,此时便可以使用本地缓存。

本地缓存的技术选型:

  • 使用 ConcurrentHashMap 作为缓存

    这个是最简单的缓存使用,但是没有一定的内存淘汰策略,用作缓存来使用,功能比较单一。需要开发人员进行定制化开发。

  • Guava Cache

    Guava是Google团队开源的一款 Java 核心增强库,包含集合、并发原语、缓存、IO、反射等工具箱,性能和稳定性上都有保障,应用十分广泛,强烈推荐。其中 Guava Cache 支持很多特性,比如:支持最大容量限制、支持两种过期删除策略(插入时间和访问时间)、支持简单的统计功能、基于LRU算法实现

  • 本文将要介绍的Caffeine缓存

    Caffeine是一个高性能的Java本地缓存库,设计用于提供快速响应时间和高并发处理能力。它具有类似于Guava缓存的简单易用的API,同时也提供了许多额外的功能和性能优化。Caffeine支持缓存大小限制、缓存过期策略、异步加载数据等特性,可以帮助开发人员在应用程序中有效地管理和优化缓存。Caffeine还提供了可自定义的缓存策略和监听器,以帮助开发人员根据实际需求定制缓存行为。

  • 基于Ehcache实现本地缓存

    Ehcache是一个流行的Java开源缓存框架,用于在应用程序中管理缓存数据。它被广泛用于提高应用程序性能,减少数据库访问频率,和减少网络开销。同Caffeine和Guava Cache相比,Ehcache的功能更加丰富,扩展性更强。

Caffeine本地缓存

在项目开发中,为提升系统性能,减少 IO 开销,采用本地缓存是必不可少的。最常见的本地缓存是 Guava 和 Caffeine。Caffeine 是基于 Google Guava Cache 设计经验改进的结果,相较于 Guava 在性能和命中率上更具有效率,你可以认为其是 Guava Plus版本。

使用步骤

步骤 1: 添加依赖

<dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>caffeine</artifactId>
    <version>3.1.5</version> <!-- 确保使用最新版本 -->
</dependency>

<!-- Spring Boot Cache 的依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

步骤 2: 配置 Caffeine 缓存管理器

package com.supermap.ai.agent.config;

import com.github.benmanes.caffeine.cache.Caffeine;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.TimeUnit;

/**
 * @Author: wangrongyi
 * @Date: 2024/7/8 14:02
 * @Description: 缓配配置类
 */
@Configuration
@Slf4j
public class CaffeineConfig {

    @Bean
    public CacheManager cacheManager() {
        CaffeineCacheManager cacheManager = new CaffeineCacheManager();
        //Caffeine配置
        Caffeine<Object, Object> caffeine = Caffeine.newBuilder()
                //最后一次写入后经过固定时间过期
                .expireAfterWrite(600, TimeUnit.SECONDS)
                //maximumSize=[long]: 缓存的最大条数
                .maximumSize(1000);
        cacheManager.setCaffeine(caffeine);
        log.info("缓存配置 CacheManager 初始化");
        return cacheManager;
    }
    
    @Bean
    public Cache<String, Object> caffeineCache() {
        log.info("缓存配置 Cache 初始化");
        return Caffeine.newBuilder()
                // 设置最后一次写入或访问后经过固定时间过期
                .expireAfterWrite(600, TimeUnit.SECONDS)
                // 初始的缓存空间大小
                .initialCapacity(1000)
                // 缓存的最大条数
                .maximumSize(1000)
                .build();
    }
}

Caffeine配置参数说明:

initialCapacity=[integer]: 初始的缓存空间大小
maximumSize=[long]: 缓存的最大条数
maximumWeight=[long]: 缓存的最大权重
expireAfterAccess=[duration]: 最后一次写入或访问后经过固定时间过期
expireAfterWrite=[duration]: 最后一次写入后经过固定时间过期
refreshAfterWrite=[duration]: 创建缓存或者最近一次更新缓存后经过固定的时间间隔,刷新缓存
weakKeys: 打开key的弱引用
weakValues:打开value的弱引用
softValues:打开value的软引用
recordStats:开发统计功能 注意:
expireAfterWrite和expireAfterAccess同事存在时,以expireAfterWrite为准。
maximumSize和maximumWeight不可以同时使用
weakValues和softValues不可以同时使用

注意: CacheManager 是使用注解形式时需要注入的Bean,Cache是在代码中显示使用时需要注入的,可以注入多个Bean,用名字区分,达到使用不通的缓存配置的效果。比如对过期时间有不通的要求,那么就可以注入两个过期时间不同的 CacheManager ,Bean的名字要做区分,在使用 @Cacheable 调用缓存时,便可以显示指定不同的 cacheManager。

步骤 3: 使用缓存

有两种使用缓存的方式:注解使用、代码显示使用

  • 注解使用

        // 获取缓存
        @GetMapping("/getCache")
        @Cacheable(value = "cache", key = "'key'")
        public String getCache() throws InterruptedException {
            Thread.sleep(3000);
            return "getCache";
        }
    
    	// 设置缓存
        @GetMapping("/setCache")
        @CachePut(value = "cache", key = "'key'")
        public String setCache() throws InterruptedException {
            Thread.sleep(3000);
            return "setCache";
        }
    
    	// 删除缓存
        @GetMapping("/delCache")
        @CacheEvict(value = "cache", key = "'key'")
        public String delCache() throws InterruptedException {
            Thread.sleep(3000);
            return "delCache";
        }
    

    注解使用说明:

    • @EnableCaching

      开启缓存功能,一般放在启动类上。

    • @CacheConfig

      当我们需要缓存的地方越来越多,你可以使用@CacheConfig(cacheNames = {“cacheName”})注解在 class 之上来统一指定value的值,这时可省略value,如果你在你的方法依旧写上了value,那么依然以方法的value值为准。

    • @Cacheable

      根据方法对其返回结果进行缓存,下次请求时,如果缓存存在,则直接读取缓存数据返回;如果缓存不存在,则执行方法,并把返回的结果存入缓存中。一般用在查询方法上。

      属性/方法名解释
      value缓存名,必填,它指定了你的缓存存放在哪块命名空间
      cacheNames与 value 差不多,二选一即可
      key可选属性,可以使用 SpEL 标签自定义缓存的key
      keyGeneratorkey的生成器。key/keyGenerator二选一使用
      cacheManager指定缓存管理器
      cacheResolver指定获取解析器
      condition条件符合则缓存
      unless条件符合则不缓存
      sync是否使用异步模式,默认为false
    • @CachePut

      使用该注解标志的方法,每次都会执行,并将结果存入指定的缓存中。其他方法可以直接从响应的缓存中读取缓存数据。一般用在新增方法上。

      属性/方法名解释
      value缓存名,必填,它指定了你的缓存存放在哪块命名空间
      cacheNames与 value 差不多,二选一即可
      key可选属性,可以使用 SpEL 标签自定义缓存的key
      keyGeneratorkey的生成器。key/keyGenerator二选一使用
      cacheManager指定缓存管理器
      cacheResolver指定获取解析器
      condition条件符合则缓存
      unless条件符合则不缓存
    • @CacheEvict

      使用该注解标志的方法,会清空指定的缓存。一般用在更新或者删除方法上。

      属性/方法名解释
      value缓存名,必填,它指定了你的缓存存放在哪块命名空间
      cacheNames与 value 差不多,二选一即可
      key可选属性,可以使用 SpEL 标签自定义缓存的key
      keyGeneratorkey的生成器。key/keyGenerator二选一使用
      cacheManager指定缓存管理器
      cacheResolver指定获取解析器
      condition条件符合则缓存
      allEntries是否清空所有缓存,默认为 false。如果指定为 true,则方法调用后将立即清空所有的缓存
      beforeInvocation是否在方法执行前就清空,默认为 false。如果指定为 true,则在方法执行前就会清空缓存
    • @Caching

      该注解可以实现同一个方法上同时使用多种注解。可从其源码看出:

      image-20240716171300420

  • 代码显示使用

        @Autowired
        private Cache<String, Object> cache;
    
        @GetMapping("/getCacheInfo")
        public void getCacheInfo() throws InterruptedException {
            String s = (String) cache.getIfPresent("key");
            if (s == null) {
                cache.put("key", "value");
                Thread.sleep(3000);
            }
            log.info("cache:{}", cache.getIfPresent("key"));
        }
    

    显示使用时需要注意处理并发读写,防止并发读写造成缓存不一致问题。

总结:使用Caffeine作为本地缓存能极大增加缓存数据的访问效率,提升读取性能。不过,本地缓存的使用受限于本地缓存的大小,所以面对缓存很大以及复杂的数据结构还是考虑用第三方的缓存服务,比如Redis。

关注不迷路。come on 在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vue2学习笔记7 - Vue中的MVVM模型

MVVM Model-View-viewModel是一种软件架构模式&#xff0c;用于将用户界面&#xff08;View&#xff09;与业务逻辑&#xff08;Model&#xff09;分离&#xff0c;并通过ViewModel进行连接和协调。MVVM模式的目标是实现视图与模型的解耦&#xff0c;提高代码的可读性、可维护…

力扣Hot100之两数之和

解法一&#xff1a; 双层循环暴力求解&#xff0c;先在数组的一个位置定住然后在这个位置的后续位置进行判断&#xff0c;如果两个数加起来等于目标和那么就返回 class Solution:def twoSum(self, nums: List[int], target: int) -> List[int]:for i,num in enumerate(num…

react Jsx基础概念和本质

什么是jsx jsx是JavaScript和XML(HTML)的缩写&#xff0c;表示在js代码中编写HTML模板结构&#xff0c;它是react中编写UI模板的方式 const message this is message function App(){return (<div><h1>this is title</h1>{message}</div>) } jsx优…

js补环境系列之剖析:原型、原型对象、实例对象三者互相转化(不讲废话、全是干货)

【作者主页】&#xff1a;小鱼神1024 【擅长领域】&#xff1a;JS逆向、小程序逆向、AST还原、验证码突防、Python开发、浏览器插件开发、React前端开发、NestJS后端开发等等 思考下&#xff1a;js补环境中&#xff0c;什么场景会用到原型、原型对象、实例对象&#xff1f; 举…

通过docker构建基于LNMP的WordPress项目

目录 1.准备nginx 2.准备mysql 3.准备php 4.构建各镜像 5.运行wordpress 1、项目环境&#xff1a; 1.1 &#xff08;1&#xff09;公司在实际的生产环境中&#xff0c;需要使用Docker 技术在一台主机上创建LNMP服务并运行Wordpress网站平台。然后对此服务进行相关的性能…

《昇思25天学习打卡营第07天|qingyun201003》

日期 心得 越往后&#xff0c;越看不懂&#xff0c;只能说是有了解到如何去训练模型代码&#xff0c;对于模型代码该如何去保存&#xff0c;如何通过网络模型去训练。只能一步步来&#xff0c;目前来说是推进度&#xff0c;等后面全部有了认知&#xff0c;再回来重新学习 昇思…

防火墙NAT地址转换和智能选举综合实验

一、实验拓扑 目录 一、实验拓扑 二、实验要求&#xff08;接上一个实验要求后&#xff09; 三、实验步骤 3.1办公区设备可以通过电信链路和移动链路上网(多对多的NAT&#xff0c;并且需要保留一个公网IP不能用来转换) 3.2分公司设备可以通过总公司的移动链路和电信链路访…

网易天音:网易云音乐推出的一站式AI音乐创作工具

网易天音是一款由网易云音乐推出的AI音乐创作工具&#xff0c;它为音乐爱好者和专业歌手提供了一个便捷高效的创作平台。用户可以通过输入灵感&#xff0c;利用AI技术辅助完成作词、作曲、编曲和演唱&#xff0c;生成初稿后还可以进行词曲协同调整&#xff0c;以满足个性化的音…

MySQL 执行引擎 事务 锁 日志

MySQL 执行引擎 事务 锁 日志 一、执行引擎二、事务三、锁四、日志 一、执行引擎 1、查询设置引擎 -- 查询当前数据库支持的存储引擎&#xff1a;默认的执行引擎是innoDB 支持事务&#xff0c;行级锁定和外键 show engines;-- 查看当前的默认存储引擎&#xff1a; show var…

5.串口通信

文章目录 串口的介绍TTLRS-232RS-485 分类方式串口并口同步异步 相关寄存器SCONPCONTMODSBUFIE 中断处理函数代码编写main.cdelay.cdelay.hUart.cUart.hmain.h回环 继电器ESP8266AT指令代码编写main.cdefine.cdefine.hsend.csend.hreceive.cdelay.cdelay.h 串口的介绍 UART&am…

Sentinel限流算法:滑动时间窗算法、漏桶算法、令牌桶算法。拦截器定义资源实现原理

文章目录 滑动时间窗算法基本知识源码算法分析 漏桶算法令牌桶算法拦截器处理web请求 滑动时间窗算法 基本知识 限流算法最简单的实现就是使用一个计数器法。比如对于A接口来说&#xff0c;我要求一分钟之内访问量不能超过100&#xff0c;那么我们就可以这样来实现&#xff1…

Java面试八股之Redis Stream的实现原理及应用场景

Redis Stream的实现原理及应用场景 Redis Stream是一种在Redis 5.0版本中引入的数据结构&#xff0c;它主要用于实现高效的消息队列服务。下面我将详细解释其实现原理以及一些常见的应用场景。 实现原理 1. 结构组成&#xff1a; - Redis Stream由一个或多个消息组成&#xf…

链接追踪系列-00.es设置日志保存7天-番外篇

索引生命周期策略 ELK日志我们一般都是按天存储&#xff0c;例如索引名为"zipkin-span-2023-03-24"&#xff0c;因为日志量所占的存储是非常大的&#xff0c;我们不能一直保存&#xff0c;而是要定期清理旧的&#xff0c;这里就以保留7天日志为例。 自动清理7天以前…

.NET MAUI开源架构_2.什么是 .NET MAUI?

1.什么是.NET MAUI&#xff1f; .NET 多平台应用 UI (.NET MAUI) 是一个跨平台框架&#xff0c;用于使用 C# 和 XAML 创建本机移动和桌面应用。使用 .NET MAUI&#xff0c;可从单个共享代码库开发可在 Android、iOS、macOS 和 Windows 上运行的应用。 .NET MAUI 是一款…

主机安全-开源HIDS字节跳动Elkeid安装使用

目录 概述什么是HIDSHIDS与NIDS的区别EDR、XDR是啥&#xff1f; Elkeid架构Elkeid Agent && Agent centerElkeid DriverElkeid RASPElkeid HUBService DiscoveryManager安装数据采集规则&告警 参考 概述 什么是HIDS HIDS&#xff08; host-based intrusion detec…

Java-寻找二叉树两结点最近公共祖先

目录 题目描述&#xff1a; 注意事项&#xff1a; 示例&#xff1a; 示例 1&#xff1a; 示例 2&#xff1a; 示例 3&#xff1a; 解题思路&#xff1a; 解题代码&#xff1a; 题目描述&#xff1a; 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科…

怎么关闭Windows安全中心?

Windows安全中心是Windows操作系统中的一项重要功能&#xff0c;系统提供这个功能的目的是保护电脑免受各种安全威胁。尽管如此&#xff0c;有时候我们可能出于某些原因需要关闭它。本文将详细介绍如何关闭Windows安全中心&#xff0c;以及需要注意的事项。 重要提醒&#xff1…

kubernetes k8s 控制器 Replicaset 配置管理

目录 1、Replicaset控制器&#xff1a;概念、原理解读 1.1 Replicaset概述 1.2 Replicaset工作原理&#xff1a;如何管理Pod&#xff1f; 2、 Replicaset资源清单文件编写技巧 3、Replicaset使用案例&#xff1a;部署Guestbook留言板 4、Replicaset管理pod&#xff1a;扩…

CUDA编程00 - 配置CUDA开发环境

第一步&#xff1a;在一台装有Nvidia显卡和驱动的机器上&#xff0c;用nvidia-smi命令查看显卡所支持cuda版本 第二步&#xff1a; 到Nvidia官网下载CUDA Toolkit并安装&#xff0c;CUDA Toolkit Archive | NVIDIA Developer 安装时按提示下一步即可&#xff0c;安装完成用 nv…

【Harmony】SCU暑期实训鸿蒙开发学习日记Day1

关于ArkTS和ArkUI&#xff0c;基础语法请看&#x1f449;官方开发手册 系统学习后&#xff0c;聊聊几个点&#xff0c;面向刚学习这门语言的小白&#xff0c;用于巩固和回顾&#x1f60b; 目录 类型推断应用 函数相关 布局方式 线性布局 堆叠布局 网格布局 弹性布局 …