菜单

异步

相关源文件

异步是构建可扩展和响应式系统的关键架构模式,它允许耗时操作独立于主应用程序流进行处理。本页涵盖异步处理技术、它们的实现以及何时在系统设计中应用它们。

有关可与异步系统一起使用的通信协议的信息,请参阅通信

概述

异步工作流有助于减少昂贵操作的请求时间,这些操作否则将在线执行。它们还可以提供一种机制,用于调度周期性批处理作业以收集数据。

来源:README.md1275-1283

消息队列

消息队列在系统组件之间接收、存储和传递消息。它们充当生产者和消费者之间的缓冲区,实现服务间的异步通信。

当进程在请求中内联执行速度过慢时,您可以使用消息队列,其工作流如下:

  1. 应用程序向队列发布作业,并通知用户作业状态
  2. 工作进程从队列中取出作业,处理它,并在完成后发出信号

用户不会被阻塞,作业在后台处理。在此期间,客户端可以选择进行少量处理,使其看起来任务已完成。

常见消息队列技术

技术特性用例
Redis简单的消息代理,可能丢失消息一些消息丢失可以接受的简单用例
RabbitMQ功能齐全,AMQP协议,需要专用节点复杂路由,保证交付
Amazon SQS托管服务,延迟较高,可能重复交付无服务器架构,AWS集成
Kafka高吞吐量,分布式提交日志日志数据,事件流,实时分析

来源:README.md1284-1299

任务队列

任务队列接收任务及其相关数据,运行它们并交付结果。它们支持调度,并能处理长时间运行的后台作业。

与只传输消息的消息队列不同,任务队列提供

  • 任务跟踪
  • 结果处理
  • 优先级管理
  • 调度能力
  • 重试机制

Celery 是一个流行的任务队列实现,它支持调度并与 Python 深度集成。

来源:README.md1300-1305

背压

当队列过大时,内存使用可能会超出容量,导致频繁进行磁盘交换并降低性能。背压是一种通过限制队列大小来缓解此问题的策略。

采用背压时

  • 当队列满时,客户端会收到“服务器忙”消息或 HTTP 503 状态码
  • 客户端可以稍后重试请求,通常使用指数退避策略
  • 系统整体吞吐量保持高位,队列中作业的响应时间保持低位

来源:README.md1306-1309

实际应用示例

社交媒体帖子分发

当用户在社交平台发布内容时,内容可能立即出现在自己的动态中,但实际向关注者分发的过程是异步进行的

图像处理

照片共享服务可能异步处理图像上传

来源:README.md1284-1299

异步的优势

  • 通过不阻塞用户界面来改善用户体验
  • 增强系统响应能力和可扩展性
  • 通过负载平滑化提高资源利用率
  • 通过重试机制提高可靠性
  • 系统组件解耦,提高可维护性

异步的缺点

  • 增加系统架构的复杂性
  • 引入处理延迟
  • 需要额外的基础设施和监控
  • 难以调试和追踪问题
  • 不适用于轻量级计算或需要即时响应的实时工作流

来源:README.md1310-1313

何时使用异步

场景建议
长时间运行的操作使用异步处理
计算密集型任务使用带工作进程池的任务队列
可能失败并需要重试的操作使用带重试逻辑的消息队列
实时/交互式要求考虑使用同步处理
轻量级操作为简单起见保持同步
批处理要求通过任务队列进行调度

实现考量

在实现异步处理时,请考虑

  1. 消息持久性 - 消息是否需要在进程/服务器重启后继续存在?
  2. 交付保证 - 您需要至少一次、至多一次还是恰好一次交付?
  3. 消息顺序 - 消息处理的顺序是否重要?
  4. 可伸缩性 - 队列和工作进程将如何随负载伸缩?
  5. 监控 - 您将如何监控队列深度、处理时间和错误?
  6. 故障处理 - 失败的任务将如何处理、重试或报告?

来源:README.md1310-1320

延伸阅读

  • 分布式系统中管理背压的模式
  • 利特尔法则(Little's Law),用于理解排队论和系统吞吐量
  • 消息队列和任务队列的区别
  • 事件驱动架构及其与异步处理的关系