跳到主要内容
英文版本为准

本页译自英文,由模型翻译。若与英文原文存在差异,以英文原文为准。

结算

ack、drop、retry 和 retry_after 在 Pulsar 上变成什么:确认,以及 Broker 计入客户端死信策略的重新投递。

处理器在 Pulsar 上的每种结果:本 crate 请求客户端做什么,Broker 又做什么处理器本 crate 调用Brokerack()ack_with_id已确认,不再发送retry()nack_with_id立即再次发送,计数 + 1retry_after(d)等待 d,然后nack_with_idd 之后再次发送,计数 + 1drop()ack_with_id已确认:消失没有结果什么也不做;客户端的计时器稍后处理ack_timeout 之后再次发送,计数 + 1只有 Shared 和 KeyShared 订阅的计数会增加:其他类型不计数
以文字阅读本图
  1. 处理器: ack(); retry(); retry_after(d); drop(); 没有结果
  2. 本 crate 调用: ack_with_id; nack_with_id; 等待 d,然后 nack_with_id; ack_with_id; 什么也不做; 客户端的计时器 稍后处理; 只有 Shared 和 KeyShared 订阅的计数会增加: 其他类型不计数
  3. Broker: 已确认, 不再发送; 立即 再次发送, 计数 + 1; d 之后 再次发送, 计数 + 1; 已确认: 消失; ack_timeout 之后 再次发送, 计数 + 1
  4. ack() → ack_with_id
  5. ack_with_id → 已确认, 不再发送
  6. retry() → nack_with_id
  7. nack_with_id → 立即 再次发送, 计数 + 1
  8. retry_after(d) → 等待 d,然后 nack_with_id
  9. 等待 d,然后 nack_with_id → d 之后 再次发送, 计数 + 1
  10. drop() → ack_with_id
  11. ack_with_id → 已确认: 消失
  12. 没有结果 → 什么也不做; 客户端的计时器 稍后处理
  13. 什么也不做; 客户端的计时器 稍后处理 → ack_timeout 之后 再次发送, 计数 + 1

每种结果都是对订阅的客户端消费者的一次调用,由订阅的驱动任务发出。ack 和 drop 都确认消息,因为 Pulsar 没有永久拒绝消息的命令:不应再回来的消息被确认,一再失败的消息则因上限进入死信主题。retry 请求 Broker 立即再次投递它。

retry_after(d) 在服务中把投递保持在未确认状态 d 这么久,然后发出同样的否定确认。等待运行在 Broker 建立连接的那个运行时上。不短于订阅 ack_timeout 的延迟会被拒绝,因为客户端的计时器会先把消息送回来。

没有处理器结算的投递保持未确认状态。设置了 ack_timeout 时,超时一过,客户端就会再次请求它,确认一页用图说明了这一点。没有设置时,只有消费者断开连接后它才会回来。

重试​

Pulsar 上的一次重试:立即或等待之后的否定确认、Broker 的重新投递,以及客户端的上限一次投递Broker 统计它的重新投递次数处理器返回retry() 或 retry_after(d)retry():立即发出否定确认retry_after(d):在进程中扣留 d,然后同上Broker 再次投递它计数 + 1客户端的死信策略:计数是否已达到 max_attempts?低于上限:处理器再次收到它到达上限:生产到死信主题,原消息已确认Exclusive 或 Failover 订阅上的上限拒绝启动:这两种类型都不统计重新投递等待期间停止,丢失的是等待而不是消息:消息仍未确认
以文字阅读本图
  1. 一次投递 Broker 统计它的重新投递次数 → 处理器返回 retry() 或 retry_after(d): 已处理
  2. 处理器返回 retry() 或 retry_after(d) → retry(): 立即发出 否定确认
  3. 处理器返回 retry() 或 retry_after(d) → retry_after(d):在进程中 扣留 d, 然后同上
  4. retry(): 立即发出 否定确认 → Broker 再次投递它 计数 + 1
  5. retry_after(d):在进程中 扣留 d, 然后同上 → Broker 再次投递它 计数 + 1
  6. Broker 再次投递它 计数 + 1 → 客户端的死信策略: 计数是否已达到 max_attempts?
  7. 客户端的死信策略: 计数是否已达到 max_attempts? → 低于上限: 处理器 再次收到它: 低于上限
  8. 客户端的死信策略: 计数是否已达到 max_attempts? → 到达上限:生产到 死信主题, 原消息已确认: 到达上限
  9. Exclusive 或 Failover 订阅上的上限 拒绝启动:这两种类型都不统计重新投递
  10. 等待期间停止,丢失的是等待而不是消息: 消息仍未确认

送回消息不需要发布任何东西:Broker 再次投递同一条消息,并为它计数。注册的 max_attempts 和死信主题变成客户端的死信策略。消息的计数低于上限时,客户端交出它,因此处理器会看到它 max_attempts 次。到达上限时,客户端把它生产到死信主题,并确认原消息。

这两项设置要一起使用:只声明其中一项的注册会拒绝启动;Exclusive 或 Failover 订阅上的上限也会拒绝启动,因为这两种订阅的消息到达时计数总是零。

计数归客户端自己所有,投递不会报告它。在 retry_after 等待期间停止的进程,丢失的是等待而不是消息:消息仍未确认,Broker 会在确认超时之后,或在消费者的连接断开后再次投递它。