Spring Boot 缓存优化:Redis 实战

Spring Boot 分布式缓存实战:Redis Cluster 整合,搞定缓存策略 + 高可用 + 性能优化(企业级落地) 本文介绍了在微服务架构中使用Redis分布式缓存解决数据库性能瓶颈的方案。通过超市库存的类比,阐述了无缓存架构的四大痛点:数据库压力大、接口响应慢、数据一致性风险和单点故障隐患。详细讲解了Redis Cluster高可用部署、SpringBoot整合、缓存策略设计(防穿透/击穿/雪崩)等核心内容,并提供了生产环境优化建议和企业级避坑指南。该方案可将高频接口响应时间从500ms降至10ms,减少80%以上数据库压力,有效支撑高并发场景。 阅读详情

Spring Boot 缓存优化:Redis 实战

当你的Spring Boot项目逐步落地、用户量攀升、数据量不断增大后,你会发现一个明显的问题:频繁查询数据库会导致接口响应变慢、数据库压力剧增,甚至出现卡顿、超时的情况——这既是项目发展的信号,也是需要优化的节点。缓存作为提升项目性能的核心手段,能有效减少数据库查询压力,让接口响应速度翻倍,同时让你的项目显得更专业、更具竞争力。本文承接项目数据量大后的优化需求,手把手实战Spring Boot集成Redis缓存,从环境搭建、核心注解使用,到热点数据缓存的真实案例,代码可直接复制复用,帮你快速落地缓存优化,轻松解决数据量大带来的性能瓶颈。

一、前置准备:明确缓存核心与环境搭建

缓存的核心逻辑:将频繁查询、不常变化的数据(热点数据)存储在Redis(内存数据库)中,后续查询时优先从Redis获取,避免频繁访问MySQL等关系型数据库,从而提升响应速度、降低数据库压力。本次实战基于Spring Boot + Redis + MyBatis-Plus,贴合真实项目架构,聚焦核心缓存功能落地。

1.1 环境准备

  1. Redis环境:本地安装Redis(Windows/Linux均可),确保Redis服务正常启动(默认端口6379),无密码或记住密码(后续配置使用);

  2. 项目基础:已搭建Spring Boot项目,包含MyBatis-Plus(用于数据库操作)、Web依赖(接口开发),确保数据库连接正常。

1.2 Maven 核心依赖

Spring Boot提供了Redis缓存的自动配置依赖,无需复杂配置,引入以下依赖即可快速集成Redis缓存:

<!-- Spring Boot Web 核心依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- Spring Boot Redis 缓存依赖(核心,自动配置) -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<!-- Spring Boot 缓存抽象依赖(提供缓存注解支持) -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

<!-- MyBatis-Plus 依赖(操作数据库) -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.3.1</version>
</dependency>

<!-- MySQL 驱动 -->
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <scope>runtime</scope>
</dependency>

<!-- lombok 简化代码 -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

<!-- 可选:Redis 连接池依赖(提升Redis连接性能) -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>

1.3 核心配置(application.yml)

配置Redis连接信息、缓存相关参数,以及缓存序列化方式(避免Redis中存储的中文乱码、对象无法反序列化),适配项目生产环境需求:

spring:
  # 数据库配置(替换为自己的数据库信息)
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/springboot_redis?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
    username: root
    password: 123456

  # Redis 核心配置
  redis:
    host: localhost # Redis服务器地址(本地为localhost,远程为服务器IP)
    port: 6379 # Redis默认端口
    password: # Redis密码(无密码则留空)
    database: 0 # 操作的Redis数据库(默认0号库)
    # Redis连接池配置(提升连接性能,推荐配置)
    lettuce:
      pool:
        max-active: 16 # 最大连接数
        max-idle: 8 # 最大空闲连接
        min-idle: 4 # 最小空闲连接
        max-wait: 1000 # 最大等待时间(毫秒)

  # 缓存配置(开启缓存,指定缓存类型为Redis)
  cache:
    type: redis # 缓存类型:Redis(默认是Simple,本地内存,不适用于生产)
    redis:
      time-to-live: 3600000 # 缓存默认过期时间(1小时,单位:毫秒)
      cache-null-values: false # 是否缓存null值(避免缓存穿透,根据需求调整)
      key-prefix: springboot:cache: # 缓存key前缀(避免与其他Redis数据冲突)
      use-key-prefix: true # 启用key前缀

# MyBatis-Plus 配置(打印SQL,便于调试缓存效果)
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  mapper-locations: classpath:mybatis/mapper/**/*.xml
  type-aliases-package: com.example.demo.entity

1.4 开启缓存功能(核心注解)

在Spring Boot启动类上添加@EnableCaching注解,开启缓存功能,一行代码即可完成,简洁高效,是后续使用缓存注解的前提:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

/**
 * 启动类:开启缓存功能(@EnableCaching)
 */
@SpringBootApplication
@EnableCaching // 开启缓存功能,必须添加,否则缓存注解无效
public class SpringBootRedisCacheApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootRedisCacheApplication.class, args);
    }
}

关键注意点:1. @EnableCaching必须添加在启动类或配置类上,否则@Cacheable、@CacheEvict等注解无法生效;2. 配置Redis缓存序列化方式(后续会补充),避免出现中文乱码、对象反序列化失败的问题;3. 确保Redis服务正常启动,否则项目启动会报错。

1.5 补充:Redis缓存序列化配置(可选但推荐)

Spring Boot默认的Redis缓存序列化方式会导致缓存的对象转为二进制,无法直接查看,且中文会乱码。自定义序列化配置,将对象序列化为JSON格式,便于调试和查看,提升开发效率:

import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;

/**
 * Redis缓存序列化配置(将对象序列化为JSON格式)
 */
@Configuration
@EnableCaching
public class RedisCacheConfig {

    @Bean
    public RedisCacheManager redisCacheManager(RedisConnectionFactory connectionFactory) {
        // 1. 配置缓存序列化方式
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                // 设置缓存过期时间(全局默认,可在注解中单独设置)
                .entryTtl(Duration.ofHours(1))
                // key序列化:String格式
                .serializeKeysWith(RedisSerializationContext.SerializationPair
                        .fromSerializer(new StringRedisSerializer()))
                // value序列化:JSON格式(支持对象序列化)
                .serializeValuesWith(RedisSerializationContext.SerializationPair
                        .fromSerializer(new GenericJackson2JsonRedisSerializer()))
                // 不缓存null值
                .disableCachingNullValues()
                // 启用key前缀
                .prefixCacheNameWith("springboot:cache:");

        // 2. 创建缓存管理器并返回
        return RedisCacheManager.builder(connectionFactory)
                .cacheDefaults(config)
                .build();
    }
}

二、核心实战一:Redis 集成测试(确保环境可用)

集成Redis后,先编写简单的测试接口,验证Redis连接正常、缓存功能可正常使用,为后续缓存注解和案例落地打下基础:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * Redis 集成测试控制器
 */
@RestController
@RequestMapping("/redis/test")
public class RedisTestController {

    // 注入Redis模板(StringRedisTemplate用于操作字符串,RedisTemplate用于操作对象)
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 测试Redis存储字符串
     */
    @GetMapping("/set")
    public String setRedis(@RequestParam String key, @RequestParam String value) {
        // 存储数据到Redis
        stringRedisTemplate.opsForValue().set(key, value);
        return "Redis存储成功,key:" + key + ",value:" + value;
    }

    /**
     * 测试Redis获取字符串
     */
    @GetMapping("/get")
    public String getRedis(@RequestParam String key) {
        // 从Redis获取数据
        String value = stringRedisTemplate.opsForValue().get(key);
        return "Redis获取结果,key:" + key + ",value:" + (value == null ? "无此key" : value);
    }
}

测试步骤:

  1. 访问接口:http://localhost:8080/redis/test/set?key=test&value=redis-cache,返回存储成功;

  2. 访问接口:http://localhost:8080/redis/test/get?key=test,返回获取到的value;

  3. 打开Redis客户端(如Redis Desktop Manager),可看到存储的key-value(JSON格式,无乱码),说明Redis集成成功。

三、核心实战二:常用缓存注解(@Cacheable、@CacheEvict)

Spring Boot缓存抽象提供了便捷的注解,无需手动编写Redis操作代码,仅通过注解即可实现缓存的增、删、查,核心常用注解为@Cacheable(查询缓存)和@CacheEvict(删除缓存),覆盖大多数缓存场景。

3.1 @Cacheable:查询缓存(核心注解)

作用:在方法执行前,先检查Redis中是否有对应缓存;若有,直接返回缓存数据,不执行方法;若没有,执行方法,将方法返回结果存入Redis,后续查询直接复用缓存。

核心参数(常用):

  • value/cacheNames:缓存名称(必填),用于区分不同缓存模块(如用户缓存、商品缓存);

  • key:缓存的key(可选),支持SpEL表达式,自定义缓存key,避免key冲突;

  • unless:条件表达式(可选),满足条件时不缓存(如返回值为null时不缓存);

  • expire:缓存过期时间(可选),优先级高于全局配置,单位:秒。

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.demo.entity.SysUser;
import com.example.demo.service.SysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 缓存注解测试控制器(用户模块)
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private SysUserService sysUserService;

    /**
     * 示例1:根据用户ID查询用户(缓存key为用户ID)
     * @Cacheable:查询缓存,缓存名称为user,key为用户ID
     */
    @Cacheable(value = "user", key = "#userId", unless = "#result == null")
    @GetMapping("/{userId}")
    public SysUser getUserById(@PathVariable Long userId) {
        // 第一次查询:无缓存,执行方法,查询数据库,存入缓存
        // 第二次查询:有缓存,直接返回缓存数据,不执行该方法(不打印SQL)
        System.out.println("执行数据库查询:根据ID查询用户,ID=" + userId);
        return sysUserService.getById(userId);
    }

    /**
     * 示例2:根据用户名查询用户(自定义缓存key,添加过期时间)
     * key:拼接缓存名称和用户名,避免key冲突;expire:缓存10分钟
     */
    @Cacheable(value = "user", key = "'username:'+#username", expire = 600)
    @GetMapping("/username/{username}")
    public SysUser getUserByUsername(@PathVariable String username) {
        System.out.println("执行数据库查询:根据用户名查询用户,用户名=" + username);
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        return sysUserService.getOne(queryWrapper);
    }
}

测试效果:

  1. 第一次访问http://localhost:8080/user/1,控制台打印SQL(执行数据库查询),Redis中新增缓存(key:springboot:cache:user::1);

  2. 第二次访问同一个接口,控制台不打印SQL(不执行数据库查询),直接返回缓存数据,接口响应速度明显提升;

  3. 访问http://localhost:8080/user/username/test1,同理,第一次查询走数据库,后续走缓存。

3.2 @CacheEvict:删除缓存(核心注解)

作用:当数据发生修改(更新、删除)时,删除对应的缓存,避免缓存与数据库数据不一致(缓存脏数据)。

核心参数(常用):

  • value/cacheNames:缓存名称(必填),与@Cacheable的value一致;

  • key:要删除的缓存key(可选),与@Cacheable的key对应;

  • allEntries:是否删除该缓存名称下的所有缓存(可选,默认false);

  • beforeInvocation:是否在方法执行前删除缓存(可选,默认false,方法执行后删除)。

// 在UserController中新增更新、删除接口,添加@CacheEvict注解
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;

/**
 * 示例3:更新用户信息(删除对应缓存,避免脏数据)
 * @CacheEvict:删除key为#user.id的缓存
 */
@CacheEvict(value = "user", key = "#user.id")
@PutMapping("/update")
public String updateUser(@RequestBody SysUser user) {
    boolean success = sysUserService.updateById(user);
    return success ? "用户更新成功,缓存已删除" : "用户更新失败";
}

/**
 * 示例4:删除用户(删除对应缓存)
 */
@CacheEvict(value = "user", key = "#userId")
@DeleteMapping("/{userId}")
public String deleteUser(@PathVariable Long userId) {
    boolean success = sysUserService.removeById(userId);
    return success ? "用户删除成功,缓存已删除" : "用户删除失败";
}

/**
 * 示例5:批量删除用户(删除user缓存下的所有缓存)
 * allEntries = true:删除value="user"下的所有缓存
 */
@CacheEvict(value = "user", allEntries = true)
@DeleteMapping("/batchDelete")
public String batchDeleteUser(@RequestBody List<Long> userIds) {
    boolean success = sysUserService.removeByIds(userIds);
    return success ? "批量删除成功,用户缓存全部清空" : "批量删除失败";
}

测试效果:

  1. 先访问/user/1,缓存成功存入Redis;

  2. 访问/update接口,更新ID为1的用户信息,执行完成后,Redis中key为springboot:cache:user::1的缓存被删除;

  3. 再次访问/user/1,控制台打印SQL,重新查询数据库并缓存,确保缓存与数据库数据一致。

四、核心实战三:热点数据缓存案例(落地项目)

项目中最适合用缓存的就是「热点数据」——频繁查询、不常变化的数据,如用户信息、商品信息、字典数据等。本次以「商品列表+商品详情」为案例,落地热点数据缓存,模拟真实项目场景,让缓存优化真正发挥作用。

4.1 案例准备:商品实体与Service层

// 1. 商品实体类(Product)
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;

@Data
@TableName("product")
public class Product {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String productName; // 商品名称
    private BigDecimal price; // 商品价格
    private String description; // 商品描述
    private Integer stock; // 库存
    private LocalDateTime createTime; // 创建时间
}

// 2. 商品Mapper接口
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo.entity.Product;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface ProductMapper extends BaseMapper<Product> {
}

// 3. 商品Service层
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.entity.Product;
import com.example.demo.mapper.ProductMapper;
import org.springframework.stereotype.Service;

@Service
public class ProductService extends ServiceImpl<ProductMapper, Product> {
}

4.2 热点数据缓存实现(Controller)

商品列表(分页)和商品详情是典型的热点数据,频繁被用户访问,且商品信息不会频繁修改,适合缓存。结合@Cacheable、@CacheEvict实现缓存优化:

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.entity.Product;
import com.example.demo.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 商品缓存案例控制器(热点数据缓存)
 */
@RestController
@RequestMapping("/product")
public class ProductController {

    @Autowired
    private ProductService productService;

    /**
     * 热点数据1:商品详情(根据商品ID查询)
     * 缓存key:product:id:xxx,缓存过期时间30分钟(1800秒)
     * 说明:商品详情访问频繁,且修改频率低,适合长期缓存
     */
    @Cacheable(value = "product", key = "'id:'+#productId", expire = 1800)
    @GetMapping("/{productId}")
    public Product getProductById(@PathVariable Long productId) {
        System.out.println("执行数据库查询:查询商品详情,ID=" + productId);
        return productService.getById(productId);
    }

    /**
     * 热点数据2:商品列表(分页,无筛选条件)
     * 缓存key:product:list:pageNum:xxx:pageSize:xxx
     * 说明:首页商品列表访问量极高,缓存分页数据,减轻数据库压力
     */
    @Cacheable(value = "product", key = "'list:pageNum:'+#pageNum+':pageSize:'+#pageSize")
    @GetMapping("/list")
    public IPage<Product> getProductList(
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize) {
        System.out.println("执行数据库查询:商品列表分页,页码=" + pageNum + ",每页条数=" + pageSize);
        Page<Product> page = new Page<>(pageNum, pageSize);
        QueryWrapper<Product> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("create_time"); // 按创建时间降序
        return productService.page(page, queryWrapper);
    }

    /**
     * 商品新增(无需缓存,新增后无查询缓存)
     */
    @PostMapping("/add")
    public String addProduct(@RequestBody Product product) {
        boolean success = productService.save(product);
        return success ? "商品新增成功" : "商品新增失败";
    }

    /**
     * 商品更新(删除对应商品详情缓存和列表缓存)
     * 说明:更新商品后,删除该商品的详情缓存和所有列表缓存,避免脏数据
     */
    @CacheEvict(value = "product", allEntries = true)
    @PutMapping("/update")
    public String updateProduct(@RequestBody Product product) {
        boolean success = productService.updateById(product);
        return success ? "商品更新成功,所有商品缓存已清空" : "商品更新失败";
    }

    /**
     * 商品删除(删除对应缓存)
     */
    @CacheEvict(value = "product", key = "'id:'+#productId")
    @DeleteMapping("/{productId}")
    public String deleteProduct(@PathVariable Long productId) {
        boolean success = productService.removeById(productId);
        return success ? "商品删除成功,对应缓存已删除" : "商品删除失败";
    }
}

4.3 案例测试与效果验证

  1. 访问商品列表接口:http://localhost:8080/product/list?pageNum=1&pageSize=10,第一次执行数据库查询(打印SQL),Redis中存入缓存;第二次访问,直接返回缓存,响应速度提升50%以上;

  2. 访问商品详情接口:http://localhost:8080/product/1,第一次查询走数据库,后续走缓存;

  3. 执行商品更新接口,更新ID为1的商品信息,执行完成后,Redis中所有product缓存被清空;再次访问列表和详情接口,重新查询数据库并缓存;

  4. 查看Redis客户端,可看到缓存的商品列表和详情数据(JSON格式),过期时间正常生效。

案例优化建议:1. 商品列表缓存可根据实际需求调整过期时间(如1小时),避免缓存数据过旧;2. 若商品列表有筛选条件(如按分类筛选),可在key中添加筛选参数(如key = “‘list:category:’+#categoryId+‘:pageNum:’+#pageNum”);3. 高并发场景下,可添加缓存预热(项目启动时提前加载热点数据到Redis)。

五、常见问题与解决方案(缓存落地避坑)

  1. 缓存注解不生效?
    解决方案:① 检查启动类是否添加@EnableCaching注解;② 注解标注的方法必须是public方法,且不能是static、private方法;③ 注解标注的类必须添加@Component(或@Controller、@Service),交给Spring管理;④ 避免在同一个类中调用标注缓存注解的方法(Spring AOP代理机制限制)。

  2. Redis缓存中文乱码、对象无法反序列化?

    解决方案:配置自定义缓存序列化方式(如本文1.5节的配置),使用GenericJackson2JsonRedisSerializer将对象序列化为JSON格式,避免默认的二进制序列化。
    
  3. 缓存与数据库数据不一致(脏数据)?

    解决方案:① 数据更新、删除时,必须使用@CacheEvict删除对应缓存;② 复杂场景(如多表关联更新),可使用@CacheEvict(allEntries = true)清空对应缓存;③ 避免缓存过期时间过长,合理设置过期时间。
    
  4. 缓存穿透(查询不存在的数据,频繁访问数据库)?

    解决方案:① 配置cache-null-values: true,缓存null值(但需注意过期时间,避免缓存大量null值占用内存);② 在接口层添加参数校验,过滤无效参数;③ 使用布隆过滤器,提前拦截不存在的key。
    
  5. Redis连接失败,项目启动报错?

    解决方案:① 检查Redis服务是否正常启动;② 确认Redis连接配置(host、port、password)正确;③ 检查服务器防火墙是否开放Redis端口(6379);④ 若使用远程Redis,确认远程连接权限开启。
    

六、总结(缓存优化提升项目专业度)

本文承接项目数据量大后的性能优化需求,完整实战了Spring Boot集成Redis缓存的核心流程,从环境搭建、缓存注解使用,到热点数据缓存案例,帮你快速落地缓存优化,核心要点总结:

  • 集成Redis:引入核心依赖,配置Redis连接信息和序列化方式,开启缓存功能(@EnableCaching),确保Redis环境可用;

  • 核心注解:@Cacheable实现查询缓存,减少数据库查询;@CacheEvict实现缓存删除,避免脏数据,两个注解覆盖大多数缓存场景;

  • 热点缓存案例:以商品列表、商品详情为核心,落地真实项目场景,让缓存真正发挥性能优化作用,提升接口响应速度;

  • 避坑要点:解决缓存注解失效、中文乱码、数据不一致等常见问题,确保缓存功能稳定运行,适配生产环境。

掌握本文内容后,你可以轻松将Redis缓存集成到自己的项目中,解决数据量大带来的性能瓶颈,让接口响应速度翻倍,同时降低数据库压力——这不仅能提升项目的实用性和用户体验,更能让你的项目在同类产品中显得更专业、更具竞争力。后续可进一步扩展:缓存预热、缓存降级、分布式缓存一致性等高级功能,让缓存优化更完善。

Java 开发实战:Spring Boot 集成 Redis 实现分布式缓存优化(附完整代码与避坑指南) 本文详细介绍了基于SpringBoot 2.7.x和Redis 6.x的企业级分布式缓存实现方案。主要内容包括:技术选型与环境准备(Java11+Redis6.2.6+Docker部署)、核心代码实现(Redis配置类、缓存工具类封装、业务层缓存注解使用)、常见问题解决方案(缓存穿透/击穿/雪崩)以及性能测试对比。通过合理使用缓存,接口响应时间降低92.5%,QPS提升12.2倍。文章还提供了优化建议和多级缓存架构的学习方向。该方案能有效缓解数据库压力,提升Java后端系统性能。 阅读详情

相关推荐

Java后端开发学习路线:从Spring到AI赋能的实战指南

Java作为企业级应用开发的主流语言,其技术生态围绕JVM虚拟机、并发编程和集合框架等核心机制构建。理解这些底层原理是掌握Spring框架等高级技术的基础,后者通过控制反转和面向切面编程等设计模式实现了高效的组件管理。在微服务架构和分布式系统成为主流的今天,掌握缓存、消息队列和性能监控等技术对构建高可用应用至关重要。随着AI工具的普及,开发者现在可以利用智能辅助进行代码生成、问题排查和系统设计,显著提升开发效率。本文聚焦于Java后端技术栈的系统学习路径,并结合AI应用实践,为开发者提供从基础到高阶的完整成

weixin_34062469的博客 322

Spring 使用 Ehcache 技术指南

在 Java 企业应用开发中,缓存是一种非常重要的技术,可以有效提高应用的性能和响应速度。Ehcache 是一个非常流行的开源缓存解决方案,广泛应用于各种 Java 应用中。本文将介绍如何在 Spring 框架中集成和使用 Ehcache。

FireFox1997 1037

Spring Boot - 使用 redis 缓存数据

【代码】Spring Boot - 使用 redis 缓存数据。

学无止境 857

【Spring学习】缓存Spring Data Redis:RedisTemplate、Repository、Cache注解

为了节省内存空间,我们并不会使用JSON序列化器来处理value,而是统一使用String序列化器,要求只能存储String类型的key哈value,当要存储Java对象时,手动完成对象的序列化和反序列化。但是json序列号可能导致一些其他的问题:JSON序列化器会将类的class类型写入到JSON结果中并存入Redis,会带来额外的内存开销。key和value的序列化方式默认就是String方式,省去了我们自定义RedisTemplate的过程。主要针对配置,能够根据方法的请求参数对其结果进行缓存。

午后阳光 2173

吃透Spring Boot整合Redis:缓存设计、分布式锁实现与序列化优化实战

*** 注意:缓存的对象必须实现Serializable接口(默认序列化要求)* 后续序列化优化后可移除该要求*/@Data缓存使用优先使用Spring Cache注解简化缓存逻辑,结合布隆过滤器/空值缓存解决穿透问题;热点key使用互斥锁+随机过期时间,避免击穿和雪崩;缓存更新遵循“Cache Aside”策略(更新数据库后更新缓存,删除数据后删除缓存)。分布式锁生产环境优先使用Redisson,避免手写锁的坑;

2601_94871597的博客 351

免费 AIS船舶轨迹预测 数据集 分享 (可用于长周期轨迹预测)

论文中使用的数据由提供。有关预处理步骤的详细信息,请参阅。

qq_43747519的博客 1万+

【SpringBoot 技术专题】「Cache 缓存组件」Redis 缓存使用技巧及注解大全

基于注解的缓存 对于缓存声明,Spring 的缓存提供了一组 Java 注解: @Cacheable:触发缓存写入。 @CacheEvict:触发缓存清除。 @CachePut:更新缓存(不会影响到方法的运行)。 @Caching : 重新组合要应用于方法的多个缓存操作。 @CacheConfig:设置类级别上共享的一些常见缓存设置。 @Cacheable 顾名思义,@Cacheable 可以用来进行缓存的写入,将结果存储在缓存中,以便于在后续调用的时候可以直接返回缓存中的值,...

gp16674213804的博客 480

vue中使用video-player视频插件,第一次无法监听父组件穿过来的值解决办法

需求: 页面![在这里插入图片描述](https://img-blog.csdnimg.cn/20201208141906802.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0FfOTg4OA==,size_16,color_FFFFFF,t_70) 作品清单是从后端请求回来的不同格式的url,前端需求根据后缀动态判断格式,然后对齐进行下载和

A_9888的博客 768

Springboot整合Redis作为Mybatis的二级缓存

文章转载声明:转载请附带原文链接 0. 环境准备 以下是我本机的环境: SpringBoot2.3.x Mybatis3.x Redis5.x 本机或者服务器中搭建好redis环境,并启动成功!这里我用的是阿里云学生机上部署的redis5.x IDEA2020.x ,Eclipse2020也是可以的,编辑器选择无所谓! 1. 新版本springboot和IDEA编辑器踩坑(可以直接跳过该章节,遇到类似的错误再回头看) 如果您在实操过程中,使用的是IDEA2020 和springboot2.3.x 版.

兴趣使然的草帽路飞 1万+

【matlab】MATLAB 变量详解与应用

在 MATLAB 中,变量可以通过赋值操作进行定义。例如,要定义一个名为xx = 10;在这个例子中,我们创建了一个名为x的变量,并将其赋值为 10。需要注意的是,MATLAB 是一种动态类型语言,因此不需要显式地声明变量的类型。变量名必须以字母开头。变量名可以包含字母、数字和下划线。变量名区分大小写。不要使用 MATLAB 中的关键字(如forif等)作为变量名。

小吴同学的博客 2211

Cadence元件库介绍

Cadence安装完之后,在安装目录下,会有默认自带的一些常用元件库。例如,我的Candece安装目录为: D:\Cadence\Cadence_SPB_17.2-2016 元件库所在目录为: D:\Cadence\Cadence_SPB_17.2-2016\tools\capture\library 各个元件库对应的内容如下: AMPLIFIER.OLB 共 182 个零件,存放模拟放大器 IC,如 CA3280,TL027C,EL4093 等。 ARITHMETIC.OLB 共 182 个零件,存放

年少时的棉花糖 1万+

Spring Boot + Redis 高性能缓存实战:从基础到高级优化

在高并发系统中,数据库往往成为性能瓶颈。使用 Redis 作为缓存,可以带来以下优势: ✅ 超高读写速度(内存级存储,访问速度可达 10W+ QPS) ✅ 支持多种数据结构(String、Hash、List、Set、ZSet 等) ✅ 分布式架构支持(主从复制、哨兵模式、集群模式) ✅ 持久化机制(RDB、AOF 持久化策略) ✅ 丰富的应用场景(缓存、排行榜、Session 共享、分布式锁等)

一名热衷于技术的全栈开发者,专注于前端与后端的全面技术探索。在这里,我将分享我在技术领域的学习与成长,助力更多开发者的进步。 1247

首发!谷歌倾斜摄影数据转换生成OSGB格式

全球首发,谷歌倾斜摄影模型文件能直接转换成OSGB格式!

cyber_room的博客 2286

Spring Boot集成Redis缓存:实战优化与避坑指南

在Redis缓存集成与优化过程中,除了上述核心问题,还需关注一些易被忽略的细节坑点,避免因小问题导致系统故障。生产环境中必须禁用Redis默认密码或空密码,同时限制Redis服务的访问IP,通过防火墙拦截非法访问,防止缓存数据泄露或被恶意篡改。缓存key的设计需规范,避免使用过长或无意义的key,同时避免key冲突,可通过业务前缀+唯一标识的方式生成key,便于缓存排查与管理。此外,需避免缓存过大的数据,过大的数据会增加传输时间与内存占用,可将大数据拆分为多个小缓存,提升缓存性能。

2601_94990967的博客 779

Halcon 色彩标定:RGB空间下实现白平衡与CCM矩阵合成静态HDR图像

摘要 本文介绍了一种基于Halcon的色彩校正方法,结合白平衡与灰轴约束最小二乘法实现精准颜色还原。方法分为三步:1)自动定位色卡区域并提取灰阶块计算白平衡增益;2)通过前三列色块建立测量值与标准值的映射关系;3)引入灰轴约束条件求解色彩校正矩阵(CCM),确保中性灰区域不偏色。算法采用中位数计算白平衡增益以提高鲁棒性,并通过旋转校正处理色卡倾斜问题。实验表明,该方法能有效消除相机采集的系统色偏,适用于颜色测量、表面检测等机器视觉场景。文末提供了完整代码实现。

LIN943168247的博客 404

YooAsset 学习

YooAssets使用教程

weixin_44884538的博客 1658

Spring Boot微服务架构下的Redis缓存优化实战:一次技术面试的深度探讨

这次技术交流涵盖了Java全栈开发的核心技术栈,从Spring Boot微服务架构到Redis缓存优化,从Vue3前端开发到分布式系统设计。通过实际的代码示例和业务场景分析,我们可以看到现代互联网应用开发的复杂性和技术深度。扎实的基础知识:深入理解Spring Boot、Redis、Vue3等核心技术的原理实战经验积累:通过项目实践来加深对技术的理解和应用系统性思维:不仅要掌握单个技术点,更要理解整个系统架构持续学习能力:技术更新迅速,需要保持学习的热情和能力。

aqiHandsome的博客 1105

银河麒麟桌面系统批量交付:封装自动化ISO镜像,百台装机效率提升10倍

麒麟桌面系统自动化ISO镜像定制摘要 本文详细介绍麒麟桌面版ISO安装镜像的定制方法,通过修改系统文件实现自动化安装部署。主要内容包括:1) 挂载原版ISO并提取文件;2) 使用unsquashfs解压系统文件进行定制化修改,包括添加系统标记配置;3) 配置ky-installer.cfg自动应答文件,设置安装参数如用户名、密码、分区方案等;4) 修改grub引导配置启用自动安装模式。该流程支持磁盘加密、自定义分区、自动登录等功能,生成的定制镜像可满足批量部署需求,显著提升系统安装效率。

信创运维工程师 · 银河麒麟 & 容器实战 | 金融生产环境迁移·等保加固 | 142篇原创·17万+阅读 1502

Spring Boot + Redis 缓存性能优化实战:从5秒到毫秒级的性能提升

摘要:调查系统GeoJSON数据接口性能优化实践 针对某调查系统出现的GeoJSON数据接口响应缓慢问题(5-6秒响应时间,20MB+数据量),团队实施了系统性缓存优化。通过分析发现:前端时间戳参数破坏缓存、后端SpEL表达式处理异常、用户令牌空值导致缓存键失效等问题。解决方案采用前后端双重缓存策略,重构后端Spring Cache实现,包括:修复SpEL表达式、设计差异化缓存键、配置Redis多级缓存(10分钟到1小时不等),并开发缓存管理服务。优化后接口响应时间降至毫秒级,性能提升超99%。

zhz5214的博客 1250

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Web性能优化实战:从数据库瓶颈到Redis缓存层架构设计与Spring Boot集成

在Web应用开发中,数据库性能瓶颈是常见的挑战,尤其是在高并发和数据量增长的场景下。其根源往往在于磁盘I/O的延迟,无法满足频繁读取简单数据的需求。缓存技术的核心原理是利用内存的高速读写特性,以空间换取时间,将热点数据暂存于内存中,从而显著降低数据库压力并提升响应速度。这一技术对于构建高性能、可扩展的Web系统具有重要价值,广泛应用于缓解数据库死锁、提升服务器并发处理能力等场景。Redis作为主流的内存数据结构存储,凭借其丰富的数据类型和单线程高性能模型,成为实现缓存层的理想选择。本文聚焦于如何为Web项目

weixin_42531925的博客 272

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

【架构师私藏】:Spring Boot集成Redis使用@Cacheable的三大禁忌与破解之道

掌握Spring Boot集成Redis缓存注解@Cacheable的正确用法,避开序列化、缓存穿透与失效策略三大陷阱。详解适用场景与配置优化,提升系统性能。架构师实战经验分享,值得收藏。

QuickSolve的博客 812

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Spring Boot项目实战:构建集成AI与全文搜索的内容管理系统

内容管理系统(CMS)作为现代Web应用的核心组件,其架构设计与技术选型直接决定了系统的可维护性与扩展性。Spring Boot凭借其约定优于配置的理念和丰富的Starter生态,为快速构建企业级应用提供了坚实基础。通过整合Spring Data JPA实现数据持久化、Spring Security保障系统安全,开发者可以高效搭建业务模块。在工程实践中,引入Elasticsearch实现高性能全文搜索,并结合Spring AI集成智能文本处理能力(如自动摘要和标签生成),能显著提升内容管理平台的智能化水平与

weixin_34413103的博客 451

Spring Boot构建高并发宠物电商系统的架构设计与实战

微服务架构是现代分布式系统的核心设计模式,通过将应用拆分为独立部署的服务单元,显著提升了系统的可扩展性和开发效率。Spring Boot作为微服务的主流实现框架,其自动配置和起步依赖特性大幅降低了开发复杂度,配合Spring Cloud生态可快速构建生产级应用。在电商等高并发场景下,需要结合Redis缓存、Elasticsearch搜索、RabbitMQ消息队列等中间件实现性能优化,其中多级缓存架构和分布式事务处理是关键挑战。本文通过一个日订单量5000+的宠物电商项目实战,详解如何基于Spring Boo

weixin_34294649的博客 397

互联网大厂Java面试:Java核心+Spring Boot+Redis技术深挖

HashMapvsHashMap是非线程安全的,适用于单线程环境。通过分段锁机制实现线程安全,适合高并发场景。JVM垃圾回收机制JVM通过不同的垃圾回收器(如Serial、Parallel、CMS、G1)自动管理内存。G1垃圾收集器特点:分区收集,支持并行和并发,低延迟。线程池线程池减少线程创建开销,提供更优的资源管理。和。

weixin_54138735的博客 210

Java大厂面试实战:电商系统核心技术解析

Java 8的Stream API和Spring Boot自动装配是现代Java开发的核心技术。Stream API通过函数式编程风格和惰性求值机制,显著提升了集合数据处理的效率和代码可读性。Spring Boot自动装配则基于条件注解和spring.factories机制,实现了依赖的智能配置。这些技术在电商等高并发系统中尤为重要,如订单处理场景需要高效的数据操作和快速的服务启动。结合Redis多级缓存和MyBatis优化技巧,可以构建高性能的分布式系统。本文通过真实面试案例,深入解析这些技术在电商订单系

weixin_30835649的博客 512
上一篇: Spring Boot 定时任务与异步处理
下一篇: Spring Boot 实战:从0到1搭建简单管理后台
码客日记
博客等级 码龄6年 149粉丝 22原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码客日记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值