英文版本为准
本页译自英文,由模型翻译。若与英文原文存在差异,以英文原文为准。
工作分区
一个订阅通过一条接收链路和一个泵任务读取它的队列;workers(n, by_key) 按 group-id 把投递分到各个工作分区上。
以文字阅读本图
- Broker 上的 队列 orders → 接收链路 信用 256:Broker 最多提前发送多少: transfer
- 接收链路 信用 256:Broker 最多提前发送多少 → 泵任务 投递等待空间时继续结算: 已接收
- 泵任务 投递等待空间时继续结算 → AmqpSubscriber 流 深度等于信用的通道: 交出
- AmqpSubscriber 流 深度等于信用的通道 → workers(2, by_key) 工作分区 = group-id 的哈希: 一次一条
- workers(2, by_key) 工作分区 = group-id 的哈希 → 工作分区 1 组 a 和 c, 各自有序
- workers(2, by_key) 工作分区 = group-id 的哈希 → 工作分区 2 组 b,有序
- 更多实例竞争同一个队列,Artemis 的 消息组把同一个 group-id 留在同一个接收者上
Broker 按链路的信用发送,默认 256 次 transfer,服务结算后客户端再授予更多信用。泵任务把每次投递交给一个深度等于信用的通道,因此服务中等待处理器的投递不会超过一份信用的量。投递等待通道腾出空间时,泵任务继续执行结算,所以即使没有人轮询流,已经交出的投递的确认也不会被卡住。
流一次产出一次投递。不用 workers 时,一个循环依次为每次投递运行处理器,队列的顺序得以保持。
workers(n, by_key) 运行 n 个工作分区。投递进入其分区键的哈希所对应的工作分区,每个工作分区按顺序运行自己的投递。分区键放在消息的 group-id 属性中,因此同一组的消息保持顺序,不同的组并行运行。没有分区键的投递也就没有工作分区的键,这样的投递轮流分配到各个工作分区。
要超出一个进程扩展服务,就在同一个 queue 地址上运行更多实例:它们的接收者相互竞争,每条消息只交给其中一个。Artemis 的消息组把同一个 group-id 的每条消息都发给同一个接收者,因此一个组跨实例也保持顺序。在 Azure Service Bus 上,group-id 就是会话 id。
批处理器接收客户端从流中组装的一个批:最多到挂载点指定的大小,batch_wait(默认 10 毫秒)一过就提前结束。信用与批的大小相互独立:信用限制 Broker 提前发送多少,批的大小是一次处理器调用看到多少条消息。