跳至内容

Odoo 19 队列作业:异步报表的用户体验

异步报表:入队、通知、附件权限与限流
2026年8月9日
Odoo 19 队列作业:异步报表的用户体验

经营导出、库存龄期、应收账龄一类大报表,如果堵在 HTTP 请求里,浏览器只会等到 504。Odoo 19 的正确体验是:用户点一次「导出/计算」→ 立刻拿到「已加入队列」反馈 → 后台 worker 写出 ir.attachment → 用活动或邮件通知下载。本文按可落地顺序写清:任务模型怎么设计、参数如何序列化、权限如何按发起人隔离、限流与失败重试怎么配,以及验收时要看哪些指标。

为什么必须异步,而不是把超时调大

反向代理 proxy_read_timeout、Odoo limit_time_cpu / limit_time_real 可以「撑」住一次长请求,但撑不住并发:午后十个人同时导出,Web worker 被占满,登录和开单也会变慢。异步把「计算」从请求线程挪到队列消费者,网关只等待入队成功(通常 < 1 秒)。若环境安装了企业队列作业,用 job 通道;否则可用专用 ir.cron + 任务表轮询,但务必给任务写状态机,禁止无状态死循环扫全库。

  • 交互请求:短超时,失败要可读。
  • 已知长任务:只同步做参数校验与入队。
  • 结果下载:走附件或签名 URL,不走内存流经 worker。

任务记录与可序列化参数

建议自建轻量模型(或复用现有 job 表)至少包含:namestate(draft/queued/running/done/failed)、user_idcompany_id、筛选条件 JSON、attachment_iderror_messagequeued_at / done_at。筛选条件只存原始 domain / 日期区间 / 报表类型,不要存不可 pickle 的 recordset。消费者里用 env['sale.order'].with_company(...).search(domain) 重建查询。同一业务键(用户+报表类型+参数哈希)若已有 queued/running,应拒绝二次入队或返回原任务,避免重复点击造出十份相同 Excel。

完成通知与附件权限

完成后创建 ir.attachmentres_model/res_id 挂在任务记录上,public=False。用 mail.activitymail.mail 通知发起人,链接指向任务表单或受控下载路由。权限规则:只有发起人、同公司管理员或明确安全组可读附件;禁止把结果挂到「全公司可读」的公告上。敏感财务导出建议设过期策略:例如 7 天后由清理 cron 把附件 datas 清空并写审计备注。

限流、失败与毒丸任务

同一 user_id 并发任务数设上限(例如 2);超大时间范围在入队前拦截并提示缩小筛选。失败要写可读 error_message(截断 traceback 前 2KB),状态置 failed,并给发起人活动。自动重试用指数退避,且同一任务最多 N 次;连续失败标「毒丸」,需人工点「重试」才再入队。运维侧监控:队列深度、平均耗时、失败率、单用户占用槽位数。

落地步骤(可照做)

  1. 选定一条最痛的报表(如库存估值导出)做试点,先不铺全站。
  2. 加「导出」按钮:校验参数 → 建任务 → 入队 → 通知「可在我的导出任务查看」。
  3. 消费者写 Excel/CSV 到附件;完成后活动提醒。
  4. 压测:同时 10 用户提交,确认 Web 仍可登录开单。
  5. 写 SOP:失败如何看错误、如何重试、谁有权下载别人的导出。

验收标准

  • 30 万行量级导出不拖垮 Web worker;页面在 2 秒内返回入队成功。
  • 完成后仅发起人(及授权角色)能打开 ir.attachment
  • 重复点击同一参数组合不会产生多份并行任务(或明确合并)。
  • 人为抛错后状态=failed,发起人收到活动,且可一键重试。

用户可见的状态机文案

任务列表显示:排队中 / 计算中 / 已完成可下载 / 失败可重试。失败文案避免堆栈原文, 给「可能原因 + 建议缩小筛选 + 联系人」。下载审计:谁在何时下载了哪份 ir.attachment。 对财务类导出启用二次确认或二次认证。定期清理过期附件并保留审计行。 若队列中间件升级,先在预生产跑「十万行导出」回归,再改生产消费者并发数。

中国Odoo网|对照 Odoo 19 企业版队列/异步报表实践整理:先入队再计算,附件按人授权,限流与失败可观测。

Odoo 19 队列作业:异步报表的用户体验
2026年8月9日
存档