高并发场景下,Spring Boot项目优先选Lettuce,因其基于Netty的响应式连接模型支持连接复用和真正异步操作,而Jedis阻塞式连接易因线程数激增导致连接池争抢、I/O等待和泄漏 当面临高并发压力时,Spring Boot项目通常会优先选择Lettuce。这个选择背后的逻辑,并非简单地
Lettuce和Jedis在SB中怎么选_高并发场景推荐Lettuce
作者:技术拾光
时间:2026-05-05
浏览:620
文章目录
高并发场景下,Spring Boot项目优先选Lettuce,因其基于Netty的响应式连接模型支持连接复用和真正异步操作,而Jedis阻塞式连接易因线程数激增导致连接池争抢、I/O等待和泄漏

当面临高并发压力时,Spring Boot项目通常会优先选择Lettuce。这个选择背后的逻辑,并非简单地追求“技术更先进”,而是基于一个更现实的考量:Lettuce依托Netty构建的响应式连接模型,天生就为连接复用和异步操作设计。相比之下,Jedis采用的阻塞式TCP连接,在并发线程数急剧攀升时,很容易成为整个系统的性能瓶颈。
为什么 Jedis 在高并发下容易扛不住
究其根本,Jedis是一个同步阻塞的客户端。它的工作模式通常是每个线程独占一个连接实例,或者从JedisPool中获取连接。这就导致了一个直接的结果:所需的连接数几乎等于并发线程数乘以每线程的连接数。一旦QPS突破数千,同时微服务实例众多,如果再开启pipeline或事务,问题便会接踵而至:
- 连接池面临频繁争抢,调用
JedisPool.getResource()时可能出现明显等待,日志里也常常见到Could not get a resource from the pool这样的报错。 - 只要Redis响应稍有延迟,比如10毫秒,那么发起请求的线程就会被卡住同样的时间,导致大量CPU资源在I/O等待上空转。
- 连接泄漏的风险显著增高。一旦忘记调用
close()或者在异常路径中未能回收连接,连接池的资源很快就会耗尽。 - 更重要的是,
Jedis并不支持真正的命令异步化。其提供的Future等异步接口,大多是在同步调用之上包装的一层,底层依然是阻塞的。
Lettuce 的连接模型怎么缓解这个问题
那么,Lettuce是如何破局的呢?它的核心在于连接模型的不同。Lettuce默认会共享一个StatefulRedisConnection(或者连接池中的少数几个连接),底层的I/O操作全部交由Netty的EventLoop来管理。所有命令都通过异步pipeline发送,真正实现了“一个连接处理大量并发请求”的理想状态:
- 从Spring Boot 2.0开始,
Lettuce已成为默认集成的Redis客户端,RedisTemplate底层会自动使用LettuceConnectionFactory。 - 连接数变得高度可控。通常单个服务实例配置1到4个
StatefulRedisConnection就足够了,连接数不再随着业务线程数的增长而线性膨胀。 - 它提供了真正的异步支持。像
connection.async().set(“k”,“v”)这样的调用,会直接返回一个RedisFuture,方便进行组合操作和超时控制。 - 自动重连机制也是一大亮点。遇到网络闪断,
Lettuce能够静默地重建连接,而使用Jedis时,开发者通常需要手动捕获JedisConnectionException并实现重试逻辑。 - 这里有个细节需要注意:如果显式地为
LettuceClientConfigurationBuilder配置了GenericObjectPoolConfig,反而会使其退化为连接池模式,从而丧失连接复用的核心优势——除非你有明确的需求,例如需要为多租户场景做连接隔离。
切换到 Lettuce 后要注意的坑
当然,技术选型的切换绝非简单地改个依赖项就万事大吉。如果不调整以下几个关键点,性能问题依然可能出现:
- 首要任务是确保没有残留的
Jedis依赖。建议通过mvn dependency:tree命令检查,并排除可能由spring-boot-starter-data-redis间接引入的jedis包,否则Spring框架可能会自动回退到Jedis。 - 连接超时配置需要留意。在默认不开启SSL和认证的情况下,
Lettuce的连接超时时间长达60秒。在生产环境中,这显然是不可接受的。务必通过clientOptions( ClientOptions.builder().socketOptions(SocketOptions.builder().connectTimeout(Duration.ofSeconds(3)).build()).build())这样的方式将其调整至一个合理的范围。 - 事务行为存在差异。
Lettuce的multi()和exec()本质上是客户端的状态管理,命令执行失败不会自动回滚。而Jedis在multi()过程中抛出异常后,连接会进入dirty状态,需要主动调用reset()。 - 在Redis集群模式下,
Lettuce能够自动处理MOVED和ASK这样的重定向指令。但对于跨槽的KEYS或SCAN操作,它依然会报错——这并非客户端的缺陷,而是Redis Cluster架构本身的限制。
说到底,决定性能上限的关键,从来不是客户端的名称本身,而是连接生命周期的管理策略是否与业务的吞吐节奏相匹配。Lettuce的优势,只有在连接被充分复用的前提下才能完全展现。如果每个HTTP请求都去新建一个RedisClient然后关闭,那么它的表现与Jedis也就没什么区别了。
实用工具推荐
电子包浆
使用 ›绿化、压缩、噪点和虚拟水印,自由调节做旧程度。
图片压缩
使用 ›选择画质和输出格式,预览压缩前后的大小。