共计 1446 个字符,预计需要花费 4 分钟才能阅读完成。
背景与痛点
小红书 Skill 系统作为平台能力扩展的重要组成部分,面临着来自用户和业务方的双重压力。主要挑战集中在以下几个方面:

- 高并发请求处理 :在促销活动或热点内容爆发时,Skill 系统的 QPS 可能瞬间增长 10 倍以上
- 技能模块的动态扩展 :业务方需要快速上线新技能,同时保证不影响已有功能的稳定性
- 服务依赖复杂 :很多技能需要调用多个内部服务,如何管理这些依赖关系成为难题
技术选型
在架构选型上,我们对比了两种主流方案:
- 单体架构
- 优点:开发简单,初期部署成本低
-
缺点:扩展性差,一个模块出问题可能导致整个系统崩溃
-
微服务架构
- 优点:模块解耦,可独立扩展和部署
- 缺点:需要额外的服务治理和监控设施
考虑到小红书 Skill 系统的特性,我们最终选择了基于 Spring Cloud 的微服务架构。以下是关键决策因素:
- 技能模块天然适合作为独立服务
- 可以针对热点技能单独扩容
- 技术栈与公司现有基础设施兼容
核心实现
技能模块的松耦合设计
我们采用契约优先的开发模式,每个技能都必须实现标准接口:
public interface Skill {String getName();
SkillResponse execute(SkillRequest request);
default boolean isAvailable() { return true;}
}
这种设计带来了以下优势:
- 新技能开发只需关注业务逻辑
- 可以动态检测技能健康状态
- 方便进行 A / B 测试和灰度发布
基于事件总线的技能调度机制
我们使用 Kafka 作为事件总线,实现技能调度的解耦。架构图如下:
graph LR
A[客户端请求] --> B[API 网关]
B --> C[技能调度服务]
C --> D[Kafka]
D --> E[技能 Worker1]
D --> F[技能 Worker2]
关键实现代码片段:
@KafkaListener(topics = "skill_requests")
public void handleSkillRequest(SkillMessage message) {Skill skill = skillFactory.getSkill(message.getSkillName());
if (skill != null && skill.isAvailable()) {SkillResponse response = skill.execute(message.getRequest());
// 异步回写结果
resultService.saveResponse(message.getRequestId(), response);
}
}
性能优化
在实践中我们总结出以下有效的优化手段:
- 多级缓存策略
- 本地缓存:使用 Caffeine 缓存技能元数据
-
分布式缓存:Redis 缓存热门技能的执行结果
-
异步处理链路
- 非核心路径采用最终一致性
-
耗时操作放入线程池处理
-
智能限流
- 基于技能重要性设置不同限流阈值
- 动态调整限流参数
避坑指南
以下是我们在生产环境中遇到的实际问题及解决方案:
-
问题 1 :技能间循环依赖导致系统死锁
解决 :建立技能依赖关系图,启动时进行环路检测 -
问题 2 :Kafka 消息堆积导致延迟增加
解决 :根据技能优先级设置不同的消费者组 -
问题 3 :缓存雪崩击穿数据库
解决 :采用二级缓存 + 空值缓存策略
总结与展望
通过微服务架构和事件驱动设计,我们构建了可扩展的小红书 Skill 系统。未来可以在以下方向继续优化:
- 引入 Serverless 架构进一步降低运维成本
- 探索技能自动编排的可能性
- 加强技能执行的可观测性
思考题 :在您的业务场景中,如何平衡技能系统的灵活性和稳定性?欢迎在评论区分享您的见解。
正文完
