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

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

结算

ack、drop、retry 和 retry_after 在 NATS 上变成什么:在 JetStream 上是服务器据以行动的确认,在 Core 上是运行时发布的副本。

处理器在 JetStream 投递上的每种结果:投递发送什么,服务器做什么处理器发送服务器ack()+ACK完成,不再发送retry()-NAK立即再次发送,delivered + 1retry_after(d)-NAK{"delay": …}扣留 d,然后再次发送,delivered + 1drop()+TERM结束,不再发送ack_wait 内没有结果什么也不发ack_wait 之后再次发送,delivered + 1在 Core NATS 上,每种结果都报告 AckError::Unsupported:服务器不结算任何东西
以文字阅读本图
  1. 处理器: ack(); retry(); retry_after(d); drop(); ack_wait 内 没有结果
  2. 发送: +ACK; -NAK; -NAK {"delay": …}; +TERM; 什么也不发; 在 Core NATS 上,每种结果都报告 AckError::Unsupported: 服务器不结算任何东西
  3. 服务器: 完成, 不再发送; 立即再次发送, delivered + 1; 扣留 d, 然后再次发送, delivered + 1; 结束, 不再发送; ack_wait 之后 再次发送, delivered + 1
  4. ack() → +ACK
  5. +ACK → 完成, 不再发送
  6. retry() → -NAK
  7. -NAK → 立即再次发送, delivered + 1
  8. retry_after(d) → -NAK {"delay": …}
  9. -NAK {"delay": …} → 扣留 d, 然后再次发送, delivered + 1
  10. drop() → +TERM
  11. +TERM → 结束, 不再发送
  12. ack_wait 内 没有结果 → 什么也不发
  13. 什么也不发 → ack_wait 之后 再次发送, delivered + 1

JetStream 投递在服务器上结算。应答发往该投递的确认 subject,消费者按消费者一页图中所示的方式处理它。retry_after 把延迟直接放进否定确认里。服务器扣留这条消息,然后在同一个消费者上再次投递它,流序号不变,delivered 计数加一。不发布任何东西,也不生成副本。

Core 投递无需结算。ack、retry 和 drop 报告 AckError::Unsupported,运行时记录日志。服务器不保存任何可以再次投递的东西,运行时只能以它发布的副本把消息带回来。这就是至多一次投递。

结果Core NATS
ack、dropAckError::Unsupported
retry()AckError::Unsupported;声明了上限时,立即发布一个副本
retry_after(d)在 d 之后发布一个副本
没有结果什么也不发生

重试​

NATS 上的一次重试:尝试上限决定是把消息带回来,还是发往死信 subject低于上限到达上限一次投递JetStream 统计投递次数;Core 靠消息头传递处理器返回retry_after(delay),或在有声明时返回 retry()max_attempts:这次尝试是否低于上限?JetStream:带延迟的 -NAK,由服务器扣留Core subject:副本发布到该 subjectCore 模式:副本发往挂载点指定的subject死信 subject:投递按到达时的原样发布没有死信:JetStream 上 +TERM,Core 上不再处理Core 副本在进程内等待它的延迟:计时器触发前停止就会丢失它
以文字阅读本图
  1. 低于上限: JetStream: 带延迟的 -NAK, 由服务器扣留; Core subject: 副本发布到 该 subject; Core 模式: 副本发往 挂载点指定的 subject
  2. 到达上限: 死信 subject: 投递按到达时 的原样 发布; 没有死信: JetStream 上 +TERM, Core 上 不再处理
  3. 一次投递 JetStream 统计投递次数;Core 靠消息头传递 → 处理器返回 retry_after(delay),或在有声明时返回 retry(): 已处理
  4. 处理器返回 retry_after(delay),或在有声明时返回 retry() → max_attempts:这次尝试是否低于上限?: 重试
  5. max_attempts:这次尝试是否低于上限? → 低于上限: 低于上限
  6. max_attempts:这次尝试是否低于上限? → 到达上限: 到达上限
  7. Core 副本在进程内等待它的延迟: 计时器触发前停止就会丢失它

上限在挂载点用 max_attempts 声明,第一次投递算作一次。在 JetStream 上,次数就是服务器自己的 delivered,因此超过 ack_wait 的投递也计算在内。在 Core 上,运行时统计它发布的副本,次数记在副本的 x-ruststream-retry-count 消息头里。

低于上限时,两种模型各自把消息带回来。JetStream 从流中重新投递它。在 Core 上,运行时把副本发布到描述符报告的地址。CoreSubject 报告它自己的 subject。CoreWildcard 匹配许多 subject,却不向任何一个发布,所以它的注册要指定副本发往的 subject,否则应用拒绝启动。

到达上限时,投递按到达时的样子发往死信 subject,载荷和消息头都不变。没有声明死信 subject 时,JetStream 投递以 +TERM 终止,Core 投递则就此放过。

本 crate 不向服务器声明任何东西:max_deliver 保持未设置,因为 JetStream 没有地方可以发送投递次数耗尽的消息。运行时的路径覆盖两种模型。