ERP 逐个调用 Magento 2 商品 REST API,更新一万条库存或价格需要数小时,于是考虑改成异步 Bulk API。Bulk 能减少客户端等待并把操作放入队列,但它不是“自动加速开关”。如果单条更新会加载完整商品、触发大量插件和索引,后台消费者仍要付出相同甚至更高成本。
先确认业务需要实时结果还是最终一致
同步 API 在响应时给出成功或错误,适合少量关键更新;异步 Bulk 通常先接受请求并返回 bulk UUID,后续由消费者处理,调用方必须查询状态并处理部分失败。价格、库存是否允许延迟几分钟,要由业务决定。
不要把巨大 Payload 当成一个 Bulk
单次包含过多操作会增加 Web 请求体、JSON 解析、队列消息和数据库事务压力。按 SKU 范围或业务批次分组,每批有稳定 ID,便于重试和对账。父子商品、网站关系和分类依赖要保持顺序,不能随机切割后并发覆盖。
消费者能力决定真实吞吐
异步 API 依赖消息队列和对应 consumer。检查队列 Ready/Unacked、consumer 数、处理速率和失败日志。盲目增加并发会把瓶颈转移到 MySQL、OpenSearch、Redis 或 ERP 回调。
bin/magento queue:consumers:list
bin/magento queue:consumers:start async.operations.all --max-messages=500
实际 consumer 名称和启动方式应以当前版本配置为准。生产环境要由进程管理器自动重启,而不是手工终端常驻。
使用正确的更新粒度
只更新库存却调用完整 ProductRepository save,会执行不必要的 EAV、URL、媒体和索引逻辑。优先使用针对库存、价格或属性的正式批量接口。自定义接口也应定义最小 service contract,不要接收整个商品对象后把空字段覆盖到数据库。
索引模式会影响导入节奏
大量更新期间若索引设为 Update on Save,每条操作同步更新索引,吞吐会明显下降。生产通常使用 Update by Schedule,但前提是 Cron 与 MView 能持续消费积压。导入结束后观察 changelog,而不是立即同时启动多个全量 reindex。
失败必须做到可定位、可重试、幂等
一个 Bulk 中可能只有部分 SKU 失败。调用方应按 operation 状态记录错误,而不是整批重新发送。每条更新带版本或业务时间戳,可以避免旧批次晚到后覆盖新值。重复消息不能重复创建属性选项或网站关系。
评估时用真实字段和插件,在 100、1000、10000 条规模下测量接收时间、最终完成时间、失败率、队列深度、数据库负载和索引延迟。Bulk 的价值是解耦与可控吞吐,最终指标应是数据在约定时间内一致,而不只是 HTTP 很快返回。

