Pulsar 订阅 backlog 持续增长,消费速率长期低于生产速率。
监控里 msgBacklog 或 backlogSize 持续上升,消费延迟变大;消息最终因 TTL/保留策略过期,或触发 backlog quota 导致生产被阻塞。消费者可能看起来仍在运行,但 msgRateOut 低于 msgRateIn。
先看 topic 和订阅级统计,区分是消费慢、未 ack 还是重投递:
pulsar-admin topics stats persistent://<tenant>/<namespace>/<topic>
pulsar-admin topics stats-internal persistent://<tenant>/<namespace>/<topic>
pulsar-admin topics subscriptions persistent://<tenant>/<namespace>/<topic>
pulsar-admin topics stats persistent://<tenant>/<namespace>/<topic> | jq '.subscriptions'
订阅下重点看 msgBacklog、unackedMessages、blockedSubscriptionOnUnackedMsgs、msgRateOut、msgRateRedeliver、lastAckedTimestamp。再从 broker 指标确认趋势:
curl -s http://<broker>:8080/metrics | grep -E 'pulsar_subscription_(msg_backlog|msg_rate_out|msg_rate_redeliver|unacked_messages|blocked_on_unacked_messages)'
curl -s http://<broker>:8080/metrics | grep -E 'pulsar_storage_(size|backlog_size|write_latency)'
检查保留、TTL 和 backlog quota,并抽样看积压消息:
pulsar-admin namespaces get-backlog-quotas <tenant>/<namespace>
pulsar-admin namespaces get-retention <tenant>/<namespace>
pulsar-admin namespaces get-message-ttl <tenant>/<namespace>
pulsar-admin topics peek-messages persistent://<tenant>/<namespace>/<topic> --count 3 --subscription <sub>
易误判:msgBacklog 包含已投递但尚未 ack 的消息(仍在 consumer 的 receiver queue 中),不等于“完全没消费”;msgBacklogNoDelayed 才排除延迟消息。若 msgRateOut 很高但 msgRateRedeliver 也高,说明在重投递空转,而不是有效吞吐。
msgRateOut 长期低于 msgRateIn。unackedMessages 增长,达到 maxUnackedMessagesPerConsumer/PerSubscription 后 blockedSubscriptionOnUnackedMsgs=true。ackTimeout 太短或处理异常,msgRateRedeliver 升高。finally 中执行;调整 ackTimeout 和 negativeAckRedeliveryDelay,避免处理未完成就重投。blockedSubscriptionOnUnackedMsgs=true,先解决 unacked 根因,而不是继续加消费者。receiverQueueSize 提高预取;同时确认 maxUnackedMessagesPerConsumer 与处理能力匹配。peek-messages 定位,确认可丢弃范围后用 skip-all-messages 或 reset-cursor 跳过。msgBacklog 高是否一定代表消费者没在处理消息?blockedSubscriptionOnUnackedMsgs=true 说明瓶颈在哪?msgRateOut 和 msgRateRedeliver 同时很高意味着什么?msgBacklog 也包含已投递但未 ack、仍在客户端队列中的消息。