惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

云风的 BLOG
云风的 BLOG
博客园 - 三生石上(FineUI控件)
WordPress大学
WordPress大学
F
Fortinet All Blogs
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 叶小钗
爱范儿
爱范儿
美团技术团队
H
Hackread – Cybersecurity News, Data Breaches, AI and More
有赞技术团队
有赞技术团队
博客园_首页
T
The Blog of Author Tim Ferriss
T
Tailwind CSS Blog
V
Visual Studio Blog
Jina AI
Jina AI
博客园 - Franky
量子位
MongoDB | Blog
MongoDB | Blog
L
LangChain Blog
Apple Machine Learning Research
Apple Machine Learning Research
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
U
Unit 42
aimingoo的专栏
aimingoo的专栏
M
MIT News - Artificial intelligence

Jiajun的技术笔记

你好,2026! TiDB 源码阅读(六):TiDB Coprocessor 源码解析 性能优化的核心思想 TiDB 源码阅读(五):索引 TiDB 源码阅读(四):AST、逻辑计划、物理计划 CockroachDB Serverless Architecture podman 无故退出 Cursor Control-L (CTRL-L) Keyboard Shortcuts in Terminal Replace docker with podman Using xmonad with xfce4 A RC script for freebsd frpc 自己动手写一个k8s controller AI 会取代你的(编程)岗位吗? 自建DERP服务器提升Tailscale连接速度(使用Nginx转发) 自动升级Docker容器 再读《程序员修炼之道-从小工到专家》 让浏览器下载文件 再读《软件随想录》/《黑客与画家》/《软技能》 HTTP 压力测试中的 Coordinated Omission 2的补码 编程语言中的 context 是什么? flutter macOS 构建出错 Flatpak 使用小记 Golang CAS 操作是怎么实现的 PostgreSQL 当MQ来使用 Clash 结合 工作VPN 的网络设计 使用 PostgreSQL 搭建 JuiceFS PostgreSQL 配置优化和日志分析 有GitHub Copilot?那就可以搭建你的ChatGPT4服务 窗口函数的使用(以PG为例)
长任务系统如何处理?
Jiajun Huang · 2023-11-12 · via Jiajun的技术笔记

长任务系统如何处理?

有时候我们会遇到一些长时间运行的任务,应该如何处理呢?可能你的第一回答是“使用异步任务”,没错,是需要使用异步任务, 但没有那么简单。常见的异步任务框架,针对的场景,大部分可能都是1分钟以内的任务,例如很多框架都会为任务设置一个超时时间。

而对于长时间运行的任务来说,很多地方是需要系统自己关心的,例如探活、实时输出信息、重试机制、排队等等。举几个常见的 场景:创建虚拟机、重度依赖AI进行分析,这些场景我们并不能简单的依赖框架,而必须要通过程序来保证可靠性。

API

  • API 除了需要做常规的权限检查之外,还需要在入队之前就确保当前队列没有超载,如果超载,则直接拒绝,这其实就是常见的“削峰”
  • 将任务的元信息保存到数据库,然后再发布任务,因为任务可能会使用到数据库,确保好这一个顺序可以避免因为时间先后导致的问题

Scheduler

  • 定期需要检查任务,例如常见的任务执行时间可能是10分钟,那么我们可以检查30分钟前开始,当前状态仍未RUNNING的任务,然后进行操作
  • 如果业务可以重试,那么需要考虑的是,在这么长时间之后,该任务是否仍然能够重试?通常对于长任务来说是不能的

Worker

  • 每次收到任务时,将任务的状态标记为RUNNING
  • 要把长任务中的任务,拆分为多个子任务,每一个子任务都需要标记状态、开始时间、结束时间等信息
  • 最好能抽象一套任务之间的依赖关系,让系统自动解决任务的依赖关系
  • 调整好任务重试的等待时间,通常对于长任务来说,任务重试等待时间越短越好,用户无法接受太长时间的等待;最好让重试的任务走一个高优先级的队列,或者无需排队等待的专有队列
  • 任务本身需要做好重试的处理,看是否能够在任务内就完成重试并且达到预期效果
  • 每个子任务完成之后,都要输出一些信息,追加一些log,这样用户可以看到当前的进度
  • 每个子任务完成之后,子任务所产生的信息、状态需要立即提交保存到数据库,避免丢失
  • 子任务要尽量设计为可重试的,状态要以数据库为准,对于核心状态信息,需要加锁确保准确更新
  • 任务完成后,将整个任务标记为DONE

监控与告警

本身对于异步任务来说,就难以观测程序的运行状态,对于长任务来说,更是如此。因此需要做好日志收集,打点操作,指标收集等工作, 同时加上告警规则,一旦发现告警,需要有工具能帮助我们快速定位问题以及观察当前运行状态。

常见的方案里,是使用OpenTracing做日志追踪和打点,Prometheus收集指标,Grafana做监控,AlertManager 做告警(或者Grafana也可以)。

需要监控的指标包含但不限于:

  • API的成功率、E2E平均执行时间、E2E P50/P90/P95执行时间
  • 业务的成功率、E2E平均执行时间、E2E P50/P90/P95执行时间
  • 任务的触发量、接受量、完成数、成功率、异常数量
  • 任务的平均执行时间、P50/P90/P95 执行时间
  • CPU 和 内存 使用量、使用率
  • 程序本身的重启次数、异常状态