已采纳
回答正文
回复
讨论正文
该问题的正文、回答与讨论。
背景
我在团队里维护一套自研 MQ Producer SDK(类似 Kafka Producer 的定位),核心特性之一是攒批:maxBatchSize=512、maxWaitMs=50(先到先发)。业务方在攒批窗口内陆续 send() 进 300~500 条消息,攒满或到时间后一次性 flush 到 broker。
同时,SDK 对外暴露一个 deliveryTimeoutMs=3000——一条消息从 send() 到 ack 回来(或明确 nack)的最长等待。这是业务方做超时补偿的锚点。
现象(痛点)
上周压测时复现了一个尴尬的时序冲突:
deliveryTimeoutMs 到期,SDK 触发超时。此时 SDK 面临一个选择:这 407 条消息该怎么处理?
deliveryTimeoutMs=3000 已经到期了,再等 50ms 虽然不多,语义上已经违约了。已尝试的排查与结果
messageId,broker 侧去重窗口 5 分钟。压测下重复率 <0.1%,但业务方吐槽"我凭什么为 SDK 的超时策略写去重逻辑?"maxWaitMs 从 50ms 缩到 10ms(让攒批窗口远小于超时),压测吞吐掉了 18%(单批从 400 条降到 80 条),broker 侧 QPS 反而升了。deliveryTimeoutMs 拉长到 10s,但业务方说"我 3s 就要拿到结果做后续流程,你 10s 我这边整个链路都超时了"。期望得到的答案形态
deliveryTimeoutMs 这个参数,在攒批场景下,你们计时起点是第一条 send() 还是 batch flush 的那一刻?这个 1~50ms 的差异在你们的线上有没有实际影响过?欢迎贴配置、贴压测数据、贴 SDK 源码片段。越具体越好,"我们就是这么干的"比"理论上应该怎样"有价值十倍。
相关参考(社区里已有讨论,但没直接覆盖这个三角交互):