苍穹外卖-缓存套餐 Spring Cache day07

Spring Cache 是 Spring 框架提供的一个缓存抽象层,它通过注解的方式简化了缓存的使用,支持多种缓存实现(如 Caffeine、Redis、EhCache 等),并统一了缓存访问的 API。以下是关于 Spring Cache 的详细介绍:

核心注解

  • @EnableCaching:用于开启 Spring Cache 功能,通常放在配置类上。

  • @Cacheable:标记方法具有缓存功能,方法的返回值会被缓存。若缓存中有数据则直接返回,否则执行方法并将结果缓存。

  • @CachePut:每次执行都会将方法的返回值放入缓存,无论缓存中是否已存在数据,常用于更新操作。

  • @CacheEvict:用于清除指定缓存,常用于删除操作。

  • @Caching:组合注解,可同时指定多个缓存规则,如同时使用 @Cacheable、@CachePut 和 @CacheEvict。

  • @CacheConfig:类级别注解,用于简化缓存配置,可在类级别定义公共的缓存配置属性。

基本使用步骤

  1. 添加依赖 :如果是 Spring Boot 项目,可使用 spring-boot-starter-cache Starter。

  2. 启用缓存 :在配置类上添加 @EnableCaching 注解。

  3. 配置 CacheManager :需注册一个 CacheManager,如 ConcurrentMapCacheManager

  4. 使用注解:在方法上使用上述注解来声明缓存规则

缓存穿透

定义:查询的Key在缓存和数据库中都不存在,导致每次请求都直接访问数据库,若大量此类请求到来,会使数据库压力骤增。

成因

  • 业务误操作,导致缓存和数据库中的数据都被误删除。

  • 黑客恶意攻击,故意大量访问不存在的数据。

解决方案

  • 缓存空对象:当查询不到数据时,将空对象或标识存储到缓存中,但需注意设置较短的过期时间,避免过多无用数据占用缓存空间。

  • 布隆过滤器:预先将所有可能存在的数据通过哈希函数映射到一个足够大的Bitmap中,查询时先通过布隆过滤器判断数据是否存在,若布隆过滤器返回不存在,则直接返回,避免查询数据库。

  • 参数校验:在接口层增加严格的参数校验,如用户鉴权校验,拦截非法请求。

  • 限流和熔断:对访问频率进行限制,当请求量超过阈值时,直接拒绝请求或返回默认值,防止数据库被过多请求冲击。

缓存击穿

定义:缓存中的某个热点数据失效,大量请求同时访问该数据,导致请求直接穿透到数据库,给数据库带来巨大压力。

成因

  • 缓存中没有热点数据的缓存,或缓存穿透导致热点数据未被缓存。

解决方案

  • 热点数据永不过期:对热点数据设置永不过期,避免其在缓存中失效,但需定期更新数据,以确保缓存数据的时效性。

  • 互斥锁机制:在缓存失效时,使用互斥锁或分布式锁,确保只有一个请求去查询数据库并更新缓存,其他请求等待锁释放后再从缓存中读取数据。

缓存雪崩

定义:大量缓存数据在同一时间过期,导致大量请求同时到达数据库,给数据库带来巨大压力,甚至可能导致数据库崩溃。

成因

  • 缓存过期策略不当,导致大量缓存同时过期。

  • 缓存服务器宕机。

解决方案

  • 设置不同的过期时间:为不同缓存设置不同的过期时间,避免大量缓存同时失效。

  • 过期时间加随机数:在设置的过期时间基础上,再加一个随机数,使缓存的过期时间分散。

  • 缓存预热:在系统启动时,预先将热点数据加载到缓存中。

  • 限流和熔断:对访问频率进行限制,当请求量超过阈值时,直接拒绝请求或返回默认值,防止数据库被过多请求冲击。

  • 本地缓存:在分布式缓存的基础上,增加本地缓存,提高缓存的可用性。

  • 双缓存:使用两层缓存,第一层缓存使用本地缓存,第二层缓存使用分布式缓存,当第一层缓存失效时,可以由第二层缓存提供数据。

  • 利用Redis集群:提高缓存服务的可用性,即使部分节点失效,也不会影响整个缓存系统的可用性

入门案例:

java 复制代码
package com.itheima.controller;

import com.itheima.entity.User;
import com.itheima.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {

    @Autowired
    private UserMapper userMapper;

    @PostMapping
//    @CachePut(cacheNames = "userCache",key = "#a0.id")//spring cache缓存
//    @CachePut(cacheNames = "userCache",key = "#p0.id")//spring cache缓存
//    @CachePut(cacheNames = "userCache",key = "#result.id")//spring cache缓存
    @CachePut(cacheNames = "userCache",key = "#user.id")//spring cache缓存
    public User save(@RequestBody User user){
        userMapper.insert(user);
        return user;
    }

    @DeleteMapping
    @CacheEvict(cacheNames = "userCache",key = "#id")
    public void deleteById(Long id){
        userMapper.deleteById(id);
    }

	@DeleteMapping("/delAll")
    @CacheEvict(cacheNames = "userCache",allEntries = true)
    public void deleteAll(){
        userMapper.deleteAll();
    }

    @GetMapping
    @Cacheable(cacheNames = "userCache",key = "#id")
    public User getById(Long id){
        User user = userMapper.getById(id);
        return user;
    }

}
相关推荐
x_feng_x3 小时前
Java从入门到精通 - 集合框架(二)
java·开发语言·windows
W.Buffer3 小时前
SpringCloud-Sentinel实战与源码分析:从流量防护到底层实现
spring·spring cloud·sentinel
Le1Yu3 小时前
雪崩问题及其解决方案(请求限流、线程隔离、服务熔断、fallback、sentinel实现以上功能)
java·开发语言
徐子童3 小时前
基于微服务的在线判题系统重点总结
java·微服务·架构
青衫码上行3 小时前
【从0开始学习Java | 第21篇】网络编程综合练习
java·网络·学习
鸽鸽程序猿4 小时前
【项目】【抽奖系统】注册功能实现
java·开发语言
沐浴露z4 小时前
【JVM】详解 运行时数据区
java·jvm
召摇4 小时前
Spring Security入门指南
后端·spring·面试
云泽8084 小时前
C/C++内存管理详解:从基础原理到自定义内存池原理
java·c语言·c++