设计 Instagram Stories:从上传到过期

发布: (2026年1月31日 GMT+8 02:08)
5 min read
原文: Dev.to

Source: Dev.to

核心需求

功能需求

  • 用户可以发布照片或视频故事
  • 故事在 24 小时后自动过期
  • 可见性受限(粉丝、亲密好友、联系人)
  • 观看者可以查看并对故事作出反应

非功能需求

  • 低延迟的动态加载
  • 高可用性
  • 横向可扩展性
  • 最终一致性是可以接受的

高层架构(HLD)

在高层次上,系统被划分为独立的服务,每个服务负责单一职责:

  • API Gateway – 身份验证、授权、路由、限流
  • Story Service – 故事创建与生命周期管理
  • Content Service – 媒体、文本和链接处理
  • Feed Service – 故事动态生成
  • Visibility Service – 隐私和受众强制执行
  • Expiration Service – 24 小时 TTL 处理
  • Kafka & Background Workers – 异步处理
  • Analytics & Notification Services – 参与度洞察和通知

故事创建流程(写路径)

用户发布故事时:

  1. 客户端通过 API Gateway 发送请求。
  2. Content Service 返回预签名的上传 URL。
  3. 客户端直接将媒体上传到对象存储(如 S3)。
  4. Story Service 保存带有 24 小时过期时间戳的元数据。

关键设计决策: 将媒体上传与元数据存储分离,使写路径保持快速且可扩展。

故事消费流程(读路径)

用户打开故事托盘时:

  1. Feed Service 从关注的用户中获取活跃的故事。
  2. Visibility Service 根据隐私规则过滤故事。
  3. 已过期的故事被忽略。
  4. 将媒体 URL 返回给客户端。
  5. 客户端直接从 CDN 流式传输媒体。

该设计针对以读取为主的流量进行了优化,因为读取流量在故事使用中占主导。

可见性和隐私规则

故事支持多种可见性模式:

  • 仅限粉丝
  • 亲密好友
  • 基于联系人的可见性(WhatsApp 状态)
  • 被屏蔽的用户

专门的 Visibility Service 使用以下方式强制执行这些规则:

  • 粉丝/联系人图谱
  • 用于快速权限检查的 Redis 缓存

将可见性逻辑隔离可确保隐私执行的一致性,并便于后续演进。

过期与生命周期管理

短暂内容被视为第一类关注点:

  • 每条故事都有严格的 24 小时 TTL。
  • Expiration Service 监控故事时间戳。
  • 过期的故事触发生命周期事件。
  • 过期内容不再提供服务。

即使在高流量情况下也能保证正确性。

使用 Kafka 的事件驱动清理

Kafka 将生命周期事件与清理逻辑解耦。典型事件包括:

  • story_created
  • story_expired
  • story_viewed
  • story_reacted

Media Cleanup Worker 订阅过期事件并执行:

  • 从对象存储中删除媒体。
  • 移除 CDN 引用。

清理工作异步进行,保持面向用户的 API 快速响应。

参与度追踪(观看与反应)

用户参与度由独立的服务处理:

  • View Tracking Service – 追踪故事观看次数。
  • Reaction Service – 点赞、表情符号和回复。

这些服务:

  • 处理极高的写入吞吐量。
  • 采用最终一致性。
  • 不影响动态读取性能。

参与度数据随后会被聚合用于分析。

最后思考

故事系统看似简单,实则复杂。通过专门为过期、可见性和规模设计,我们能够构建出弹性好、效率高且易于演进的系统。该设计与 Instagram、WhatsApp 等平台在大规模处理短暂内容的方式高度相似。欢迎提供反馈和替代方案。

Back to Blog

相关文章

阅读更多 »

API Gateway 的工作原理

什么是 API Gateway?API Gateway 是一个单一入口点,接收所有客户端请求并将其路由到相应的后端服务,同时处理……