Spring Boot中Redisson与Lettuce的高效实践之法

文章标题:

Spring Boot中Redisson与Lettuce的高效运用之道

文章内容:在Spring Boot环境下,Redisson与Lettuce的高效协同实践方案,本文将从推荐缘由、配置与维护、代码使用示例、代码验证、总结对比、常见问题解答以及实施建议等多方面展开详细阐述。

主流Java Redis客户端(Jedis、Lettuce、Redisson)差异对比-
CSDN博客

目录

1. 为何推荐Redisson与Lettuce共存?

2. 配置与维护建议

application.yml文件

redisson.yaml

pom依赖

3. 代码中使用示例

1. Lettuce的使用方式(通过Spring Data Redis)

2. Redisson的使用方式(注入RedissonClient)

4. 验证Lettuce作为默认客户端

5. 总结对比

6. 常见问题

7. 最终实施建议


1. 为何推荐Redisson与Lettuce共存?
维度 Lettuce承担的角色 Redisson承担的角色 共存优势
功能定位 基础键值操作/会话管理 分布式锁/布隆过滤器/分布式集合 避免功能重叠,各展其长
性能优化 高并发读写(毫秒级响应) 分布式场景下的原子操作 Lettuce处理高频基础操作,Redisson专注复杂分布式逻辑
资源开销 轻量级连接(单连接多路复用) 分布式对象管理 避免Redisson超15MB的包体积对基础操作性能的影响
生态整合 Spring Boot默认集成 分布式架构扩展 既可用Spring Data Redis标准API,又能享受分布式能力
运维复杂度 自动连接管理 分布式状态维护 隔离基础连接和分布式组件的故障域

典型场景

  • 用户会话管理(Lettuce) + 订单分布式锁(Redisson)

  • 商品缓存读取(Lettuce) + 秒杀库存扣减(Redisson分布式原子操作)

  • 基础数据存储(Lettuce) + 实时推荐布隆过滤器(Redisson)


2. 配置与维护建议
application.yml文件

放置于src/main/resources/下

若为application.properties文件,配置内容相同,仅需按.properties文件格式排版

# application.yml
spring:
  data:
    redis:
      # Lettuce基础配置 (Spring Boot自动装配)
      host: redis-primary
      port: 6379
      password: pass123
      lettuce:
        pool:
          max-active: 16   # 生产环境建议16-64
          max-idle: 8
          min-idle: 4

      # Redisson独立配置,单独创建一个yaml文件放在src/main/resources/下 (不共享连接池,建议用yaml)
      redisson:
        config: classpath:redisson-config.yaml
redisson.yaml

放置于src/main/resources/下

# redisson-config.yaml (单独配置文件)
#单机节点配置示例
singleServerConfig:
  address: "redis://127.0.0.1:6379"
  password: "123456"
  database: 11
  timeout: 5000
  connectionPoolSize: 256 #单个Redis节点的最大连接数(默认值:64;提高此值可支持更高并发请求,但不超Redis服务端限制)
  connectionMinimumIdleSize: 64 #单个Redis节点最小空闲连接数(默认值:24;忽略idleConnectionTimeout配置,保持活跃的连接数,通常设为connectionPoolSize的1/4左右)
  idleConnectionTimeout: 3000  #空闲连接超时时间(默认值:10000毫秒,连接空闲多久后关闭释放资源,太短频繁创建销毁连接;太长占内存)
  pingConnectionInterval: 2000  #心跳间隔时间(默认值:0-不发心跳,维持连接活跃,推荐设为比Redis服务端空闲连接超时时间略短)

#集群配置示例
#clusterServersConfig:
#  nodeAddresses:
#    - "redis://192.168.0.1:6379"
#    - "redis://192.168.0.2:6379"
#    - "redis://192.168.0.3:6379"
#  password: "your-cluster-password"  # 如有密码保护
#  database: 5                        # 默认为0,集群模式下通常忽略该参数
#  timeout: 5000                     # 连接超时时间(毫秒)
#  connectionPoolSize: 256           # 每个节点的最大连接数
#  connectionMinimumIdleSize: 64     # 每个节点最小空闲连接数
#  idleConnectionTimeout: 3000       # 空闲连接超时时间(毫秒)
#  pingConnectionInterval: 2000      # 心跳间隔(毫秒),维持连接活跃
pom依赖

排除jedis依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
        <version>2.7.4</version>
        <exclusions>
            <exclusion>
                <groupId>redis.clients</groupId>
                <artifactId>jedis</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

维护建议

  1. 连接隔离 :Lettuce连接业务Redis,Redisson连接分布式专用Redis

  2. 监控分离

    • Lettuce:监控连接池利用率 (spring.data.redis.lettuce.pool.*)

    • Redisson:监控分布式对象状态 (RedissonClient.getNodesGroup().pingAll())

  3. 版本控制

     // build.gradle
     ext {
         lettuceVersion = '6.2.6.RELEASE'
         redissonVersion = '3.23.2'
     }
     dependencies {
         implementation "org.springframework.boot:spring-boot-starter-data-redis"
         implementation "org.redisson:redisson-spring-boot-starter:${redissonVersion}"
         // 排除潜在冲突
         configurations.all {
             exclude group: 'io.lettuce', module: 'lettuce-core' 
             exclude group: 'org.redisson', module: 'redisson-spring-data-*'
         }
     }
    

3. 代码中使用示例
1. Lettuce的使用方式(通过Spring Data Redis)

注入RedisTemplate或StringRedisTemplate即可:

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

@Service
public class CacheService {

    private final StringRedisTemplate redisTemplate;

    public CacheService(StringRedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    public void set(String key, String value) {
        redisTemplate.opsForValue().set(key, value);
    }

    public String get(String key) {
        return redisTemplate.opsForValue().get(key);
    }
}
2. Redisson的使用方式(注入RedissonClient)
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class DistributedLockService {

    private final RedissonClient redissonClient;

    public DistributedLockService(RedissonClient redissonClient) {
        this.redissonClient = redissonClient;
    }

    public void acquireLock(String lockKey) {
        RLock lock = redissonClient.getLock(lockKey);
        boolean isLocked = false;
        try {
            isLocked = lock.tryLock(10, 30, TimeUnit.SECONDS);
            if (isLocked) {
                // 执行业务逻辑
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            if (isLocked && lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }
}
// 基础操作使用Lettuce (通过Spring Data Redis)
@RestController
public class CacheController {

    @Autowired
    private StringRedisTemplate redisTemplate; // 基于Lettuce

    @PostMapping("/user")
    public void saveUser(@RequestBody User user) {
        // 基础KV操作
        redisTemplate.opsForValue().set("user:"+user.getId(), 
            objectMapper.writeValueAsString(user));

        // Session管理 (Spring Session自动使用Lettuce)
        redisTemplate.opsForHash().put("session:active", 
            session.getId(), user.getId());
    }
}

// 分布式功能使用Redisson
@Service
public class OrderService {

    @Autowired
    private RedissonClient redisson; // 独立注入

    public void processOrder(String orderId) {
        RLock lock = redisson.getLock("order_lock:" + orderId);
        try {
            lock.lock(10, TimeUnit.SECONDS); // 分布式锁

            RBloomFilter<String> bloomFilter = redisson.getBloomFilter("processed_orders");
            bloomFilter.tryInit(1000000L, 0.01); // 布隆过滤器

            if (!bloomFilter.contains(orderId)) {
                // 分布式集合操作
                RSet<String> processingSet = redisson.getSet("processing_orders");
                processingSet.add(orderId);

                // ...业务逻辑
                bloomFilter.add(orderId);
            }
        } finally {
            lock.unlock();
        }
    }
}

4. 验证Lettuce作为默认客户端
@SpringBootTest
public class ClientVerificationTest {

    @Autowired
    private RedisConnectionFactory connectionFactory;

    @Test
    public void verifyLettuceClient() {
        // 验证1:检查连接工厂类型
        assertTrue(connectionFactory instanceof LettuceConnectionFactory);

        // 验证2:获取原生连接对象
        try (RedisConnection conn = connectionFactory.getConnection()) {
            LettuceConnection lettuceConn = (LettuceConnection) conn;
            System.out.println("Lettuce version: " + 
                lettuceConn.getNativeConnection().getOptions().getVersion());
        }

        // 验证3:查看依赖树 (Gradle)
        // ./gradlew dependencies | grep lettuce
        // 应包含: io.lettuce:lettuce-core:6.x.x
    }
}


import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
//验证是否使用的是Lettuce而非Jedis
@Component
public class RedisClientChecker {

    private final RedisConnectionFactory redisConnectionFactory;

    public RedisClientChecker(RedisConnectionFactory redisConnectionFactory) {
        this.redisConnectionFactory = redisConnectionFactory;
    }

    @PostConstruct
    public void checkClient() {
        String clientType = redisConnectionFactory.getClass().getName();
        if (clientType.contains("Lettuce")) {
            System.out.println("当前Redis客户端为Lettuce");
        } else if (clientType.contains("Jedis")) {
            System.out.println("当前Redis客户端为Jedis,请检查依赖排除");
        } else {
            System.out.println("当前Redis客户端未知:" + clientType);
        }
    }
}

5. 总结对比
对比维度 纯Lettuce方案 纯Redisson方案 Lettuce+Redisson组合方案
基础操作性能 ⭐⭐⭐ (10万+ QPS) ⭐⭐ (6万 QPS) ⭐⭐⭐ (Lettuce处理基础)
分布式能力 ❌ 需自行实现 ⭐⭐⭐ 开箱即用 ⭐⭐⭐ (Redisson负责)
资源开销 ⭐⭐⭐ (低内存/CPU) ⭐ (15MB+ JAR/高内存) ⭐⭐ (隔离关键组件)
配置复杂度 ⭐ (Spring Boot自动配置) ⭐⭐ (需独立配置) ⭐⭐ (双配置但清晰隔离)
架构扩展性 ⭐⭐ (需定制分布式逻辑) ⭐⭐ (强分布式弱基础) ⭐⭐⭐ (按需扩展)
推荐场景 纯缓存/会话管理 强分布式系统 企业级应用最佳实践

6. 常见问题

❓ 是否可以在application.yml中直接配置Redisson?
可以,但不推荐。Redisson配置项较多,放于redisson.yaml更清晰。
❓ Redisson会影响Lettuce的连接吗?
不会。只要它们使用不同连接池和配置,互不影响。
❓ Redisson和Lettuce是否会重复建立连接?
可能会,但可控。可将Redisson配置为共享连接池,或调整其连接池大小以适应系统负载。

❓ SpringBoot中使用Lettuce +Redisson时,一般会把那个自动装配关闭,等使用时,在手动实例化比较好?

✅ 场景一:推荐默认启用自动装配(适用于大多数项目)
✔️ 推荐方式:
Lettuce:保持Spring Boot自动装配(spring-boot-starter-data-redis)
Redisson:保持redisson-spring-boot-starter自动装配
📌 原因:
自动装配简化开发:Spring Boot自动完成配置、初始化、连接池管理等繁琐工作。
生产级配置支持良好:Spring Boot和Redisson Starter均提供丰富配置项(YAML/Properties),满足大部分场景。
资源统一管理:便于与Spring生命周期、健康检查、监控集成。
✅ 适用场景:
普通业务系统
无需多个Redis实例或复杂隔离的项目
开发效率优先于极致性能调优

✅ 场景二:建议手动实例化(高级用法)
⚠️ 当有以下需求时,建议关闭自动装配:

需求 是否建议手动实例化
使用多个Redis实例(如主从、跨集群) ✅ 是
对Redisson或Lettuce连接池进行细粒度控制(如动态扩缩容) ✅ 是
需要自定义连接池参数、SSL、超时策略等 ✅ 是
需要与已有组件兼容(如旧版SDK) ✅ 是

1. 禁用Redisson自动装配(不使用starter)

<!-- 改为使用redisson-core而非redisson-spring-boot-starter -->
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.23.5</version>
</dependency>

然后手动配置RedissonClient:

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RedissonConfig {

    @Bean
    public RedissonClient redissonClient() {
        Config config = new Config();
        config.useSingleServer()
              .setAddress("redis://127.0.0.1:6379")
              .setConnectionPoolSize(64)
              .setIdleConnectionTimeout(10000);

        return Redisson.create(config);
    }
}

2. Lettuce可继续使用自动装配
除非需要多个Redis数据源,否则无需替换Spring Data Redis提供的RedisTemplate。

7. 最终实施建议
  1. 组件边界
Spring Boot中Redisson与Lettuce的高效实践之法
  1. 部署拓扑

     +------------------+     +-------------------+
     |  Spring Boot App |     |  Redis Cluster    |
     |                  |     |                   |
     |  +------------+  |     | +---------------+ |
     |  | Lettuce    |-----> | | Business Node | |
     |  +------------+  |     | +---------------+ |
     |                  |     |                   |
     |  +------------+  |     | +---------------+ |
     |  | Redisson   |-----> | | Distributed   | |
     |  +------------+  |     | |   Node        | |
     |                  |     | +---------------+ |
     +------------------+     +-------------------+
    
  2. 升级路径

    • 新项目:直接采用组合方案

    • 旧项目迁移:

Spring Boot中Redisson与Lettuce的高效实践之法

组合方案核心价值 :在享受Spring生态便捷性的同时,获得企业级分布式能力,且通过资源隔离保障基础服务性能稳定性。

版权声明:程序员胖胖胖虎阿 发表于 2025年7月9日 下午8:55。
转载请注明:Spring Boot中Redisson与Lettuce的高效实践之法 | 胖虎的工具箱-编程导航

相关文章

暂无评论

暂无评论...