生产接入检查清单
教程跑通只证明编译、链接和基本语义正确。真正接入服务前,还要把 Executor 放进应用的生命周期、容量和故障模型中。本页按接入顺序给出一套最小评审清单。
如果项目仍在使用 detached thread、std::async 或自建任务队列,先阅读从现有线程代码迁移;检查已完成的设计时,可用并发架构反模式从症状反查。
1. 确定运行时 owner
默认单例适合进程内共享线程池;独立 Executor 实例适合测试隔离、插件隔离或不同组件需要独立关闭的场景。不要在每次请求中创建 Executor,也不要让多个模块都认为自己可以关闭共享单例。
在设计文档中明确:
- 谁在第一次提交前调用
initialize_ex(); - 谁可以更新 failure callback 和监控配置;
- 谁在停止接收新请求后发起等待与
shutdown(); - 哪些组件只借用 Executor,绝不拥有其生命周期。
2. 用真实负载设定容量
默认配置适合开始验证,不代表适合生产。至少估算峰值到达率、任务执行时间和可接受排队时间,再确定 min_threads、max_threads 与 queue_capacity。
队列容量不是越大越安全:大队列可能把过载表现从“快速拒绝”变成“长时间处理陈旧工作”。如果数据过时后没有价值,应在业务入口合并、覆盖或拒绝,而不是无限排队。
task_timeout_ms 是软超时观察机制,不会强制终止任意业务函数。网络、文件和设备 I/O 仍应配置自己的超时。
3. 给每类工作选择完成边界
| 工作类型 | 推荐完成边界 | 退出时策略 |
|---|---|---|
| 请求内计算 | 保存 future,并在请求预算内 get() | 返回成功或明确错误 |
| 后台批处理 | 保存全部 futures 或批次状态 | 有界等待,记录未完成数量 |
| fire-and-forget | callback/status + 业务关联 ID | 明确允许完成或丢弃 |
| 软周期维护 | task ID + 周期状态 | 先取消,再等待在途工作 |
| 实时控制 | realtime status + drop/timeout counters | 先停止生产者,再停实时线程 |
如果说不清某个 future、task ID 或实时任务名称由谁持有,生命周期设计还没有完成。
4. 建立三层失败观察
单次调用、服务趋势和诊断上下文回答的是不同问题:
单次结果 future.get()
服务级趋势 get_failure_status() + monitoring
最近故障上下文 set_failure_callback() + get_recent_failures()callback 应只做短小、非阻塞的事件转交。复杂格式化、网络上报和重试应放到应用自己的日志或告警线程。最近失败缓冲是有限诊断窗口,不是审计日志。
为以下事件分别设阈值,不要只告警 total_count:任务异常、提交拒绝、等待超时、实时 drop、GPU failure 和 tuning fallback 的处理动作不同。通信组件的 drop、overwrite、stale 与 missed phase 默认属于组件本地统计,也要单独接入。
5. 所有等待都必须有预算
请求线程不要无界等待未知工作。使用 future 自身的等待能力控制单项结果;服务排空使用 wait_for_completion_ex(timeout),超时时读取 CompletionStatus 的 active、queued 和 pending 数量。
等待超时后的动作应提前决定:
- 继续等待一小段时间并升级告警;
- 停止接收新工作,只允许在途任务完成;
- 进入
shutdown(false),接受未完成工作的业务后果; - 将未完成输入持久化后交给下次启动恢复。
库无法替应用选择数据一致性策略。
6. 按顺序关闭
推荐退出顺序:
- 对外标记 draining,停止接收新请求。
- 停止定时器、设备回调和其他任务生产者。
- 取消普通周期任务。
- 停止实时任务的上游推送,再停止实时线程。
- 有界等待普通异步任务,并记录状态快照。
- 根据等待结果调用
shutdown(true)或明确选择快速关闭。 - 最后销毁任务引用的数据、日志与通信基础设施。
反过来先销毁业务对象,再等待捕获这些对象的异步任务,是典型的 use-after-free 来源。
7. 用过载测试验证设计
正常 smoke test 看不到容量问题。发布前至少构造以下情况:
- 任务生产速度暂时高于消费速度;
- 某个任务抛异常,callback 自身也抛异常;
- 一个任务超过请求等待预算;
- 关闭过程中仍有生产者尝试提交;
- 实时队列满或对象池耗尽;
- GPU 后端、设备或运行时不可用;
- Linux 实时权限或亲和性配置无法应用。
验收标准不是“进程没崩溃”,而是调用方获得明确返回,计数器发生预期变化,日志能定位 executor/task,并且关闭仍在预算内完成。
最小评审结论模板
Executor owner:
初始化配置与依据:
任务类型与提交接口:
future / task ID owner:
过载策略:
失败告警入口与阈值:
单项等待预算 / 排空预算:
关闭顺序:
实时或 GPU 降级行为:
验证过的故障场景: