SpringBoot集成Lettuce连接Redis:从配置到高并发实战与调优
1. 项目概述与核心价值最近在几个项目里我又一次用到了SpringBoot集成Lettuce连接Redis这套组合。说实话这套东西现在几乎是Java后端开发的标配了但每次配置和调优时总能发现一些新的细节和“坑”。网上很多教程只告诉你“怎么配”却很少深入讲“为什么这么配”以及“配不好会怎样”。今天我就结合自己最近一次在微服务项目中处理高并发缓存场景的实际经历来拆解一下SpringBoot集成Lettuce连接Redis的完整方法、核心配置项背后的逻辑以及那些只有踩过坑才知道的实战经验。无论你是刚接触SpringBoot的新手还是想优化现有项目Redis连接的老手这篇文章都能给你提供可以直接“抄作业”的配置和避坑指南。简单来说Lettuce是一个高性能、线程安全的Redis客户端它基于Netty实现了非阻塞的I/O连接可以复用特别适合在SpringBoot这种现代应用框架中管理Redis连接池。相比于老牌的JedisLettuce在连接管理和高并发下的表现通常更胜一筹。接下来我会从环境搭建、配置详解、高级特性集成到生产环境调优一步步带你走完整个流程。2. 环境准备与基础集成2.1 项目依赖引入集成第一步就是在pom.xml里把依赖加对。这里有个关键选择你是直接用Spring Boot的spring-boot-starter-data-redis还是单独引入Lettuce对于绝大多数情况我强烈推荐前者。dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-redis/artifactId /dependency这个starter默认就包含了Lettuce客户端版本由Spring Boot的Bill of Materials (BOM)统一管理能避免版本冲突。你不需要、也不应该再单独声明lettuce-core的依赖除非你有非常特殊的版本需求。我见过有同事画蛇添足又加了一遍结果因为版本不匹配启动时直接报ClassNotFoundException。检查依赖是否引入成功可以运行mvn dependency:tree | grep lettuce。如果看到类似io.lettuce:lettuce-core:6.x.x的输出就说明一切正常。2.2 基础配置文件详解依赖加好后接下来就是在application.yml或application.properties里配置连接信息。这里面的每一个参数都直接影响着应用的性能和稳定性。spring: data: redis: # Redis服务器地址生产环境建议用域名方便切换 host: 127.0.0.1 # 默认端口就是6379如果改了记得对应上 port: 6379 # 如果没有设置密码这里可以省略。但生产环境一定要设 # password: your-strong-password-here # 默认使用0号数据库范围是0-15 database: 0 # 连接超时时间单位毫秒。默认是2000ms网络不好或Redis压力大时可以适当调高 timeout: 2000ms # Lettuce客户端特定配置 lettuce: pool: # 连接池最大连接数。这是最重要的参数之一设小了会限制并发设大了浪费资源。 max-active: 8 # 连接池最大空闲连接数。建议和max-active设置成一样避免频繁创建销毁连接。 max-idle: 8 # 连接池最小空闲连接数。保持一定数量的“热”连接应对突发请求。 min-idle: 0 # 获取连接时的最大等待时间毫秒。如果连接池耗尽新的请求会等待这个时间超时则抛异常。 # 设置为-1表示无限等待生产环境不建议容易导致线程挂死。 max-wait: -1ms注意max-active这个值不是越大越好。它应该根据你应用的实际并发量和Redis服务器的处理能力来定。一个简单的估算方法是max-active ≈ (应用最大并发线程数 / 每个操作的平均耗时) * 安全系数(如1.2)。盲目设置成50或100可能会导致Redis服务器连接数爆满反而拖累整体性能。我一般会从8开始根据监控逐步调整。配置完成后Spring Boot会自动为你配置一个RedisTemplate和StringRedisTemplateBean。你可以直接在Service里用Autowired注入它们来操作Redis。基础集成到此就完成了应用已经可以正常启动并连接Redis。3. 核心配置项深度解析与调优很多开发者配置完基础连接就觉得万事大吉其实这才刚刚开始。Lettuce和Spring Data Redis提供了大量可调优的参数理解它们才能发挥最大效能。3.1 Lettuce连接池配置的底层逻辑上面配置中的lettuce.pool部分实际上使用的是Apache Commons Pool 2。这里重点讲两个容易出问题的参数max-wait和test-on-borrow。max-wait默认是-1ms意味着当连接池耗尽时申请线程会无限期等待直到有连接被释放。这在测试环境可能没问题但在生产环境是极其危险的。想象一下某个慢查询占用了大量连接后续所有请求都会卡住最终导致整个应用线程池耗尽服务雪崩。我的经验是生产环境一定要设置一个合理的等待时间比如1000ms1秒。超时后快速失败让上层业务有降级或重试的机会。lettuce: pool: max-wait: 1000ms另一个隐藏配置是test-on-borrow。默认是false即从池中借出连接时不会先检查连接是否有效。如果Redis服务器重启过应用池里的连接就都成了“僵尸连接”下次使用时会报错。虽然Lettuce有自动重连机制但借出时检查一下更保险。你可以通过自定义配置Bean来开启它注意这会有轻微性能开销。3.2 客户端选项与SSL/TLS加密对于安全性要求高的环境比如连接云Redis服务需要配置SSL和客户端名称。spring: data: redis: host: your-redis-host.com port: 6379 password: ${REDIS_PASSWORD} ssl: true # 启用SSL加密传输 client-name: my-springboot-app # 设置在Redis端显示客户端名称便于监控和排查 lettuce: shutdown-timeout: 100ms # 应用关闭时等待连接池关闭的超时时间client-name是个非常实用的小功能。当你在Redis服务器上用CLIENT LIST命令时能看到每个连接的名称。如果某个应用连接数异常通过这个名称可以快速定位源头。3.3 序列化器配置避免存储乱码Spring Boot默认的RedisTemplate使用JdkSerializationRedisSerializer它序列化后的键值对在Redis里是二进制格式通过redis-cli直接看是乱码而且不同JVM版本可能不兼容。在生产项目中我百分百推荐改用StringRedisSerializer和GenericJackson2JsonRedisSerializer。你需要自己配置一个RedisTemplateBeanConfiguration public class RedisConfig { Bean public RedisTemplateString, Object redisTemplate(RedisConnectionFactory connectionFactory) { RedisTemplateString, Object template new RedisTemplate(); template.setConnectionFactory(connectionFactory); // 使用String序列化Key StringRedisSerializer stringSerializer new StringRedisSerializer(); template.setKeySerializer(stringSerializer); template.setHashKeySerializer(stringSerializer); // 使用Jackson序列化Value Jackson2JsonRedisSerializerObject jsonSerializer new Jackson2JsonRedisSerializer(Object.class); ObjectMapper om new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.activateDefaultTyping(om.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL); jsonSerializer.setObjectMapper(om); template.setValueSerializer(jsonSerializer); template.setHashValueSerializer(jsonSerializer); template.afterPropertiesSet(); return template; } }这样配置后存入的Java对象会被序列化成JSON字符串可读性极佳也方便其他非Java语言客户端读取。但要注意Jackson反序列化时需要类型信息上面配置中的activateDefaultTyping会在JSON中加入类信息可能会带来安全风险。对于完全可控的内部服务可以这么用如果存的是简单类型String, Long直接用StringRedisSerializer也行。4. 高级特性集成与实战案例4.1 实现分布式锁分布式锁是Redis的经典应用场景。虽然Redisson客户端功能更全但用Lettuce配合Spring Data Redis也能实现一个可靠的锁。关键是要处理好锁的原子性、超时和释放。Component public class RedisDistributedLock { Autowired private StringRedisTemplate stringRedisTemplate; private static final String LOCK_PREFIX “LOCK:”; private static final long DEFAULT_EXPIRE_TIME 30000L; // 30秒锁超时防止死锁 /** * 尝试获取锁 * param lockKey 锁的业务键 * param requestId 请求标识可用UUID用于安全释放锁 * param expireTime 锁持有时间毫秒 * return 是否获取成功 */ public boolean tryLock(String lockKey, String requestId, long expireTime) { String key LOCK_PREFIX lockKey; // 使用SET命令的NX不存在才设置和PX毫秒级过期参数保证原子性 Boolean success stringRedisTemplate.opsForValue() .setIfAbsent(key, requestId, expireTime, TimeUnit.MILLISECONDS); return Boolean.TRUE.equals(success); } /** * 释放锁 - 使用Lua脚本保证原子性 */ public boolean releaseLock(String lockKey, String requestId) { String luaScript “if redis.call(‘get’, KEYS[1]) ARGV[1] then “ “return redis.call(‘del’, KEYS[1]) “ “else “ “return 0 “ “end”; DefaultRedisScriptLong script new DefaultRedisScript(luaScript, Long.class); Long result stringRedisTemplate.execute(script, Collections.singletonList(LOCK_PREFIX lockKey), requestId); return result ! null result 1L; } }实操心得释放锁时绝对不能先get判断再del删除因为这不是原子操作在并发下极有可能释放了其他客户端的锁。必须使用Lua脚本将判断和删除作为一个命令执行。另外锁的过期时间expireTime要设置得比业务操作时间稍长但也不能太长我一般根据业务平均耗时再加一个缓冲时间比如5-10秒来设定。4.2 发布订阅Pub/Sub功能集成Lettuce原生支持响应式编程但用Spring Data Redis的模板方式实现Pub/Sub也很简单。你需要配置一个消息监听容器和一个消息处理器。Configuration public class RedisPubSubConfig { Bean public RedisMessageListenerContainer messageListenerContainer(RedisConnectionFactory connectionFactory, MessageListenerAdapter listenerAdapter) { RedisMessageListenerContainer container new RedisMessageListenerContainer(); container.setConnectionFactory(connectionFactory); // 订阅一个叫 ‘news’ 的频道 container.addMessageListener(listenerAdapter, new ChannelTopic(“news”)); // 还可以订阅模式匹配的频道如 ‘news.*’ // container.addMessageListener(listenerAdapter, new PatternTopic(“news.*”)); return container; } Bean public MessageListenerAdapter listenerAdapter(RedisMessageReceiver receiver) { // 指定接收消息的方法名 return new MessageListenerAdapter(receiver, “receiveMessage”); } } Component public class RedisMessageReceiver { private static final Logger logger LoggerFactory.getLogger(RedisMessageReceiver.class); // 这个方法名要和上面Adapter里指定的一致 public void receiveMessage(String message, String channel) { logger.info(“从频道 [{}] 收到消息: {}”, channel, message); // 这里处理你的业务逻辑 } }发布消息就更简单了Autowired private StringRedisTemplate stringRedisTemplate; public void sendNews(String news) { stringRedisTemplate.convertAndSend(“news”, news); }注意事项Redis的Pub/Sub是“即发即弃”的如果订阅者不在线消息就丢了。它不适合做可靠的消息队列。如果需要持久化、确认机制应该考虑使用Redis Streams或者专业的消息中间件如Kafka、RocketMQ。4.3 管道Pipeline与事务操作对于需要批量执行多个Redis命令的场景管道Pipeline可以大幅减少网络往返时间RTT。Lettuce底层是支持管道的通过Spring Data Redis可以这样用public ListObject batchGetWithPipeline(ListString keys) { return stringRedisTemplate.executePipelined((RedisCallbackObject) connection - { StringRedisConnection stringConn (StringRedisConnection) connection; for (String key : keys) { stringConn.get(key); // 将多个get命令放入管道 } return null; // 返回值本身被忽略结果从返回的List中获取 }); }需要注意的是管道内的命令没有原子性保证。如果需要原子性应该使用事务multi/exec。Spring Data Redis提供了SessionCallback或TransactionCallback来支持事务但Redis的事务和关系型数据库的事务ACID不是一回事。它仅仅是确保一个队列中的命令顺序执行且不会被其他客户端打断但不支持回滚。某个命令失败后面的命令依然会执行。5. 生产环境运维与故障排查5.1 连接监控与健康检查应用上线后必须监控Redis连接的状态。Spring Boot Actuator提供了/actuator/health端点集成了Redis健康指示器。确保在application.yml中开启management: endpoints: web: exposure: include: “health,info,metrics”访问/actuator/health会看到redis的状态是UP还是DOWN。更细粒度的监控可以暴露Lettuce的指标management: metrics: export: prometheus: enabled: true endpoint: metrics: enabled: true然后你可以通过/actuator/metrics/redis.connections.active等端点查看活跃连接数、空闲连接数等关键指标并集成到PrometheusGrafana中做可视化报警。5.2 常见问题排查实录问题一连接超时ConnectionTimeoutException这是最常见的问题。表现是应用启动或运行一段时间后报io.lettuce.core.RedisConnectionException: Unable to connect to Redis或超时错误。排查思路网络检查先用telnet或nc命令测试从应用服务器到Redis服务器的IP和端口是否能通。配置检查核对application.yml中的host、port、password是否正确。特别注意如果Redis配置了requirepass但应用没配密码或者密码错了连接会直接被拒。防火墙/Security Group检查服务器和云服务商的防火墙规则是否放行了6379端口。Redis服务状态登录Redis服务器用redis-cli ping检查服务是否正常运行用info clients查看当前连接数是否达到maxclients上限。客户端配置检查spring.redis.timeout和lettuce.pool.max-wait是否设置得太短。在网络延迟较高的环境如跨机房需要适当调大。问题二连接泄露Connection leak表现是监控发现活跃连接数持续增长直到达到max-active上限然后开始报获取连接超时的错误。根本原因代码中从连接池获取了连接RedisConnection但没有正确关闭。虽然RedisTemplate帮我们管理了连接的生命周期但如果你直接使用RedisConnectionFactory获取原生连接进行操作就必须手动关闭。解决方案使用try-with-resources语句确保连接关闭。try (RedisConnection connection redisConnectionFactory.getConnection()) { connection.set(“key”.getBytes(), “value”.getBytes()); } // 这里会自动调用connection.close()将连接归还给池或者优先使用RedisTemplate或RedisCallback让框架管理连接。问题三序列化/反序列化错误表现是存进去的数据取不出来或者取出来是乱码控制台报ClassCastException或Jackson反序列化错误。排查思路确认序列化器检查你的RedisTemplate配置的KeySerializer和ValueSerializer是否一致。存和取必须使用相同的序列化器。检查JSON类型信息如果你用GenericJackson2JsonRedisSerializer存了一个User对象那么反序列化时User类必须在类路径上且Jackson的默认类型配置DefaultTyping要匹配。有时不同服务甚至同一服务不同版本的类全限定名变了就会导致反序列化失败。手动清理数据如果Redis里已经存在用旧序列化方式存储的脏数据最好的办法是直接连上Redis用DEL命令删除有问题的key或者写一个临时脚本用正确的序列化方式重新写入。5.3 性能调优建议连接池大小再次强调max-active不是越大越好。一个基准测试方法是在模拟生产流量的压力测试下观察Redis服务器的CPU使用率、网络IO和连接数。逐步增加max-active直到Redis服务器指标如CPU达到瓶颈或应用端获取连接的等待时间不再显著下降。这个值就是最优值。合理使用数据结构根据业务场景选择最合适的Redis数据结构。比如存储用户会话用String或Hash实现排行榜用Sorted Set存储好友关系用Set。选对了数据结构性能和内存使用都能得到优化。避免大Key和热Key单个String类型的Value不要超过10KB集合元素不要超过5000个。热Key访问频率极高的Key会导致单实例压力过大考虑用本地缓存如Caffeine做一层屏蔽或者将热Key拆分成多个子Key。启用Lettuce的Command Tracing在排查复杂性能问题时可以开启Lettuce的追踪功能查看每个命令的执行时间。logging: level: io.lettuce.core.protocol: DEBUG # 或 TRACE 获取更详细日志注意这会产生大量日志只在排查问题时临时开启。6. 总结与个人实践体会SpringBoot集成Lettuce连接Redis从“能用”到“好用”再到“稳定高效”中间隔着无数个配置细节和实战经验。回顾整个过程我认为最重要的几点是第一理解配置背后的含义。不要复制粘贴配置尤其是连接池参数和超时时间。它们必须根据你的实际业务流量、网络环境和Redis服务器性能来调整。我习惯在项目初期设置相对保守的值然后结合APM监控如SkyWalking、Pinpoint和Redis的INFO命令输出在压测和灰度发布阶段进行反复调整。第二序列化器是稳定性的基石。从一开始就使用StringRedisSerializer和Jackson2JsonRedisSerializer组合能避免后期数据迁移的巨大麻烦。对于简单的值直接用String对于对象用JSON并谨慎处理类型信息。第三监控和告警要前置。不要等到线上出问题了才去查。一定要把Redis连接数、命令耗时、内存使用率、Key数量等核心指标纳入监控大盘并设置合理的告警阈值。比如连接池活跃连接数持续超过max-active的80%就应该触发告警。最后关于客户端选型Lettuce在大多数Spring Boot场景下都是最佳选择它的异步、响应式特性和连接池管理做得很好。但如果你需要大量使用分布式锁、Bloom过滤器等高级数据结构Redisson提供的封装更完善可以直接考虑引入。没有银弹根据你的核心需求来做技术选型。在实际编码中我还会把一些通用的Redis操作如分布式锁、缓存工具类封装成项目内部的Starter或通用模块这样在新项目中就能快速复用保证最佳实践的一致性。毕竟稳定可靠的缓存层是支撑高并发系统的关键组件之一。

相关新闻

Java基础面试核心考点与避坑指南

Java基础面试核心考点与避坑指南

1. 为什么Java基础面试题如此重要?作为从业十年的Java开发者,我面试过数百名候选人,也经历过无数次被面试。Java基础知识的掌握程度,往往直接决定了面试的成败。很多候选人把精力放在框架和项目经验上,却忽视了基础知识…

2026/8/23 5:19:06 阅读更多 →
层次分析法(AHP)详解:从多准则决策到权重计算与一致性检验

层次分析法(AHP)详解:从多准则决策到权重计算与一致性检验

1. 项目概述:从“拍脑袋”到“算脑袋”的决策利器在数学建模竞赛或者日常的复杂决策中,我们常常面临一个困境:面对多个备选方案,每个方案又受到多个相互关联、甚至重要性不同的准则影响,我们该如何科学地、量化地做出最…

2026/8/23 5:19:06 阅读更多 →
边缘AI盒子实战指南:从核心架构到七大场景落地

边缘AI盒子实战指南:从核心架构到七大场景落地

1. 项目概述:当AI“盒子”遇见真实世界最近几年,边缘AI盒子这个词在安防、物联网和智慧城市圈子里火得不行。简单来说,它就是一个集成了AI算力、能直接处理视频流的专用硬件设备。和传统方案把视频全部上传到云端服务器分析不同,边…

2026/8/23 5:19:06 阅读更多 →

最新新闻

数学建模竞赛解题框架:从问题拆解到模型构建与算法实现

数学建模竞赛解题框架:从问题拆解到模型构建与算法实现

1. 项目概述:从“解题”到“建模”的思维跃迁“2021华为杯数学建模D题完整思路”,这个标题背后,远不止一份答案或一套代码。它指向的是一个系统工程,一次从现实问题抽象到数学模型,再通过算法求解并回归现实解释的完整…

2026/8/23 5:58:16 阅读更多 →
企业私有化部署选型指南:为什么越来越多的开发团队选择自建云盘

企业私有化部署选型指南:为什么越来越多的开发团队选择自建云盘

企业私有化部署选型指南:为什么越来越多的开发团队选择自建云盘 很多开发团队在项目推进过程中,都会遇到一个共同的问题:文件怎么管。代码有Git管,但项目文档、设计稿、需求方案、验收报告这些资产,丢在共享盘里乱成一…

2026/8/23 5:58:16 阅读更多 →
物理约束下基础模型的智能体进化:从MoE架构到硬件协同部署

物理约束下基础模型的智能体进化:从MoE架构到硬件协同部署

1. 项目概述:当基础模型“长出”手脚与感官最近在跟几个做机器人和具身智能的朋友聊天,大家都有一个共同的感受:那些动辄千亿、万亿参数的“庞然大物”式基础模型(Foundation Models),能力确实惊人&#xf…

2026/8/23 5:58:16 阅读更多 →
前端转大模型:能跑Demo的人很多,能把权限日志补全的很少

前端转大模型:能跑Demo的人很多,能把权限日志补全的很少

聊《别急着换赛道:前端经验在 AI 项目里到底值多少?》之前,先说一句实在的:别急着背概念,先看它在真实项目里到底解决什么问题。摘要上周帮朋友review他刚做完的AI项目,一个基于LangChain的客服Agent&#…

2026/8/23 5:58:16 阅读更多 →
理解Java泛型:让代码更安全、更简洁

理解Java泛型:让代码更安全、更简洁

一个没有泛型的Java世界,是什么样的?你从ArrayList里取出一只Dog,编译器却只肯保证它是Object。你小心翼翼地强转,运行到一半,ClassCastException砸在你脸上。更糟糕的是,这种错误发生在毫秒之间&#xff0…

2026/8/23 5:58:16 阅读更多 →
C++刷题统计工具:从STL容器到JSON持久化的工程实践

C++刷题统计工具:从STL容器到JSON持久化的工程实践

1. 项目概述:为什么“刷题统计”是C学习者的必修课?如果你正在学习C,无论是为了准备面试、参加算法竞赛,还是单纯想夯实编程基础,那么“刷题”这件事你一定不陌生。每天在LeetCode、牛客网、洛谷等平台上解决几道算法题…

2026/8/23 5:57:16 阅读更多 →

日新闻

[光学原理与应用-521]:对光的错误理解与纠偏

[光学原理与应用-521]:对光的错误理解与纠偏

首先光是一种能量的载体和形态,宏观上观察到的光是由无数个微观的光量子组成的,每个光子在产生的瞬间,其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前,在微观层面,每个光量子的运动轨迹是以波函数所展现…

2026/8/23 0:00:50 阅读更多 →
SIP通话转接原理与REFER方法实战解析

SIP通话转接原理与REFER方法实战解析

1. 通话转接不是“挂断再拨号”,而是SIP会话的动态重定向你有没有遇到过这样的场景:客服坐席A正在和客户通电话,突然需要把这通对话无缝转给专家坐席B,客户完全感知不到中间的断连——既没听到忙音,也没被要求重新拨号…

2026/8/23 0:00:50 阅读更多 →
Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

1. 为什么选择Kolla-ansible来部署单节点OpenStack?如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法,那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

2026/8/23 0:00:50 阅读更多 →

周新闻

[光学原理与应用-521]:对光的错误理解与纠偏

[光学原理与应用-521]:对光的错误理解与纠偏

首先光是一种能量的载体和形态,宏观上观察到的光是由无数个微观的光量子组成的,每个光子在产生的瞬间,其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前,在微观层面,每个光量子的运动轨迹是以波函数所展现…

2026/8/23 0:00:50 阅读更多 →
SIP通话转接原理与REFER方法实战解析

SIP通话转接原理与REFER方法实战解析

1. 通话转接不是“挂断再拨号”,而是SIP会话的动态重定向你有没有遇到过这样的场景:客服坐席A正在和客户通电话,突然需要把这通对话无缝转给专家坐席B,客户完全感知不到中间的断连——既没听到忙音,也没被要求重新拨号…

2026/8/23 0:00:50 阅读更多 →
Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

1. 为什么选择Kolla-ansible来部署单节点OpenStack?如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法,那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

2026/8/23 0:00:50 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/22 18:08:39 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/22 7:31:03 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/22 3:22:48 阅读更多 →