首页 > 系统相关 >Spring Boot —— Caffeine(内存缓存器)

Spring Boot —— Caffeine(内存缓存器)

时间:2023-12-21 11:33:11浏览次数:34  
标签:缓存 String Spring Boot Caffeine static 内存 public

项目中需要用一个替代concurrenthashmap 能够帮忙过期或者防止一直put oom所以使用

 

优点
内存管理优化
Caffeine 使用了一种基于堆外内存的存储模型,通过直接内存访问,避免了 Java 堆内存的垃圾回收开销。这种内存管理优化可以减少垃圾回收对应用性能的影响,提供更高的缓存读写性能。
高效的缓存策略
Caffeine 提供了多种缓存策略,包括基于容量、基于时间、基于引用等。这些策略可以根据应用的需求进行灵活配置,以获得最佳的缓存性能和命中率。
并发性能优化
Caffeine 在并发访问时表现出色。它采用了细粒度的锁机制和无锁的数据结构,有效地减少了并发冲突的影响,并提供了较低的锁竞争和高并发的访问性能。
功能丰富
Caffeine 提供了丰富的功能,例如异步加载、缓存监听器、过期策略、缓存统计等。这些功能可以帮助开发者更好地控制和管理缓存,满足各种业务需求。
对比
Guava Cache 相比
Caffeine 在读写性能、并发性能、内存管理方面有明显的提升,并提供了更多的配置选项和功能扩展。
Ehcache 相比
Caffeine 在读写性能、并发性能、内存管理方面也表现出更好的性能,并且具有更灵活的缓存策略和配置选项。
Redis 等远程缓存存储进行比较时
Caffeine 作为本地缓存库具有更低的访问延迟和更高的吞吐量,适用于高性能的本地缓存场景。
适用场景
高并发读写
Caffeine 在并发读写的场景下具有出色的性能表现。如果你的应用需要处理大量并发的读写操作,例如缓存数据的读取和更新,Caffeine 可以提供高吞吐量和低延迟的访问性能。

低延迟要求
Caffeine 采用了一些优化技术,如直接内存访问和细粒度的锁机制,以降低访问延迟。如果你的应用对于低延迟的响应非常关键,例如实时数据查询或高频率的请求处理,Caffeine 可以提供快速的缓存访问,以满足这些要求。

内存敏感应用
Caffeine 提供了高效的内存管理策略,可以优化内存使用并减少垃圾回收的开销。如果你的应用在内存敏感的环境中运行,例如云计算平台或资源受限的设备,Caffeine 可以帮助减少内存占用并提高应用的可伸缩性。

热数据缓存
Caffeine 提供了多种缓存策略,包括基于容量、基于时间和基于引用的策略。这使得 Caffeine 在热数据缓存方面非常适用,可以根据数据的访问频率和最近使用时间来调整缓存策略,以提高热数据的命中率。

本地缓存需求
Caffeine 是一个本地缓存库,适用于需要在应用内部管理和存储数据的场景。相比于远程缓存方案,本地缓存具有更低的访问延迟和更高的吞吐量,特别适用于需要快速访问和频繁更新的数据。

总体而言,Caffeine 适用于需要高性能、低延迟、内存敏感以及本地缓存需求的应用场景。它在处理并发访问、内存管理、缓存策略和性能优化方面具有优势,并提供了丰富的功能和配置选项,能够满足各种应用需求。

实战
Github 链接

<dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>caffeine</artifactId>
    <!-- jdk8用2.x.x -->
    <!-- jdk11+用3.x.x -->
    <!-- 版本3.x.x是通过java11编译的 -->
    <version>2.9.3</version>
</dependency>

工具类

public class CaffeineUtil {

    /**
     * 缓存的最大容量
     */
    private static final int MAXIMUM_SIZE = 1000;

    /**
     * 缓存项的写入后过期时间
     */
    private static final int EXPIRE_AFTER_WRITE_DURATION = 30;

    /**
     * 过期时间单位(分钟)
     */
    private static final TimeUnit EXPIRE_AFTER_WRITE_TIMEUNIT = TimeUnit.MINUTES;

    private static Cache<String, Object> cache;

    /**
     * 初始化Caffeine缓存配置
     */
    static {
        cache = Caffeine.newBuilder()
                .maximumSize(MAXIMUM_SIZE)
                .expireAfterWrite(EXPIRE_AFTER_WRITE_DURATION, EXPIRE_AFTER_WRITE_TIMEUNIT)
                .build();
    }

    /**
     * 获取缓存值
     *
     * @param key 缓存键
     * @return 缓存值
     */
    public static Object get(String key) {
        return cache.getIfPresent(key);
    }

    /**
     * 设置缓存值
     *
     * @param key   缓存键
     * @param value 缓存值
     */
    public static void put(String key, Object value) {
        cache.put(key, value);
    }

    /**
     * 移除缓存项
     *
     * @param key 缓存键
     */
    public static void remove(String key) {
        cache.invalidate(key);
    }

    /**
     * 清空缓存
     */
    public static void clear() {
        cache.invalidateAll();
    }

    /**
     * 获取缓存中的所有值
     *
     * @return 缓存中的所有值集合
     */
    public static Collection<Object> getAllValues() {
        return cache.asMap().values();
    }

    /**
     * 清空缓存中的所有值
     */
    public static void removeAllValues() {
        cache.invalidateAll();
    }
}

使用

@Service
public class CaffeineServiceImpl implements CaffeineService {

    @Override
    public Result operate() {
        // 向缓存中放入数据
        CaffeineUtil.put("key1", "value1");
        CaffeineUtil.put("key2", "value2");

        // 从缓存中获取数据
        String value1 = String.valueOf(CaffeineUtil.get("key1"));
        String value2 = String.valueOf(CaffeineUtil.get("key2"));
        // 输出: Value 1: value1
        System.out.println("Value 1: " + value1);
        // 输出: Value 2: value2
        System.out.println("Value 2: " + value2);

        Collection<Object> values = CaffeineUtil.getAllValues();
        for (Object value : values) {
            System.out.println("所有Value:"+value);
        }

        // 从缓存中移除数据
        CaffeineUtil.remove("key2");

        // 再次获取数据
        String value2AfterInvalidation = String.valueOf(CaffeineUtil.get("key2"));
        // 输出: Value 2 after invalidation: null
        System.out.println("Value 2 after invalidation: " + value2AfterInvalidation);

        return Result.success();
    }

}

单元测试

@Slf4j
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = CaffeineApplication.class)
public class CaffeineServiceImplTest {

    @Autowired
    private CaffeineServiceImpl caffeineService;

    @Before
    public void before() throws Exception {
    }

    @After
    public void after() throws Exception {
    }

    @Test
    public void method() {
        log.info(JSONObject.toJSONString(caffeineService.operate()));
    }

}

 

标签:缓存,String,Spring,Boot,Caffeine,static,内存,public
From: https://www.cnblogs.com/shanheyongmu/p/17918635.html

相关文章

  • Spring Boot原理分析 | SpringApplication、Yaml、Properties
    ......
  • 如何用MyEclipse搭建JSF/Primefaces和Spring(一)
    本教程将引导大家完成为JavaServerFaces(JSF)生成软件组件的过程,在本文中您将学习到如何:从数据库表到现有项目搭建配置支持JSF2.0的服务器部署搭建的应用程序自定义Spring代码生成需要MyEclipse Spring或Bling授权。MyEclipsev2023.1.2离线版下载MyEclipse技术交流群......
  • Spring Boot 3.2 + CRaC = 王炸!
    原文:https://foojay.io/today/springboot-3-2-crac/前段时间发布了Spring6.1和SpringBoot3.2,它们都完全支持CRaC(检查点协调恢复)。如果你想了解有关CRaC的更多信息,请随时阅读此处:https://docs.azul.com/core/crac/crac-introductionCRaC是一个OpenJDK项目,可以“快......
  • Spring基于注解的IOC配置
    目录基于注解的IOC配置1、用于创建对象的注解2、用于注入数据的3、用于改变作用范围的和生命周期相关基于注解的IOC配置曾经XML的配置<beanid="accountService"class="com.zjw.service.impl.AccountServiceImpl"scope=""init-method=""destroy-method=""><pro......
  • 【SpringBootWeb入门-16】Mybatis-基础操作-多条件查询操作&XML文件配置SQL
    1、章节回顾上一篇文章我们讲解了Mybatis的增改查操作,本篇继续学习Mybatis的复杂查询操作(多条件查询)。2、增删改查操作-多条件查询操作根据条件姓名、性别、入职时间来查询员工表emp数据,其中员工姓名支持模糊匹配,性别进行精确匹配,入职时间进行范围查询,查询结果按照最后修改时间......
  • spring eureka服务注册配置,排查服务注册上来了,但是请求没有过来。检查是否服务注册配
    springeureka服务注册配置,排查服务注册上来了,但是请求没有过来。检查是否服务注册配置错误解决方法:去掉该配置eureka.instance.hostname=client微服务的提供IP地址//微服务的提供IP地址,点开服务注册的http://xxx:1246,找到服务,点开的是client微服务:微服务端口号,检......
  • SpringAOP之@Transactional处理事务
    跟着孙哥学Spring,b站:https://www.bilibili.com/video/BV185411477k/?spm_id_from=333.337.search-card.all.click引言在现代的Java应用开发中,Spring框架提供了丰富的功能来简化复杂性。其中,事务管理是一个至关重要的部分。@Transactional注解为我们提供了一种便捷的方式来声......
  • Spring中的依赖注入DI
    目录Spring中的依赖注入DISpring中的依赖注入DI依赖注入的简单理解就是给对象设置变量值。Spring配置文件<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSch......
  • Spring Boot学习随笔- 文件上传和下载(在线打卡、附件下载、MultipartFile)
    学习视频:【编程不良人】2021年SpringBoot最新最全教程第十二章、文件上传、下载文件上传文件上传是指将文件从客户端计算机传输到服务器的过程。上传思路前端的上传页面:提交方式必须为post,enctype属性必须为multipart/form-data开发后端的Controller后端方法接收参数......
  • spring gateway 超时重试和默认拦截器配置
    spring:cloud:gateway:default-filters:-name:Retryargs:retries:3RetryConfig中默认的异常处理为IOException.class,TimeoutException.classpublicstaticclassRetryConfigimplementsHasRouteId{ privateStrin......