PubSubInboundChannelAdapter接收4条消息后停止工作求助
TemporaryReplyChannel.receive()) It looks like you’ve done a great job narrowing down the issue to thread blocking on the temporary reply channel—let’s break down the root causes and actionable fixes that don’t just involve cranking up thread counts.
Context Recap
You built a simplified Spring Boot app to reproduce a production issue:
- It receives messages from Google Pub/Sub, logs them, and sends an ACK back
- Core components include:
- Config class:
@Slf4j @Configuration public class MyConfig implements FlowSupport { ... } - Message handler:
@Component @Slf4j public class EmptyNotificationHandler implements GenericHandler<Notification> { ... } - ACK handler:
@Component public class MyPubSubAckHandler implements MessageHandler { ... }
- Config class:
The problem: The first message works perfectly (logs appear, ACK is sent, GCP shows 0 unacked messages), but after a few successful runs, the app stops receiving new messages. Debugging reveals threads stuck on org.springframework.messaging.core.GenericMessagingTemplate.TemporaryReplyChannel#receive(long):314 at this.replyLatch.await();.
Why This Happens
Your hypothesis about the MessageDispatcher failing to execute tasks is on track—but the root trigger is likely that the Spring messaging framework is waiting for a reply that never arrives. The TemporaryReplyChannel is created when the framework expects a synchronous response from your handler, but if no reply is sent, the thread blocks indefinitely, eating up the subscriber thread pool. Once the pool is exhausted, no new deliverMessageTask can run, so the app stops processing messages.
Fixes That Don’t Require Increasing Threads
1. Eliminate Synchronous Reply Expectations
Double-check your messaging flow and handler:
- If you’re using
MessagingTemplate.sendAndReceive()anywhere, switch tosend()instead—you don’t need a reply for Pub/Sub ACK handling. - Ensure your
EmptyNotificationHandlerreturnsnullexplicitly. Older Spring Cloud GCP versions can misinterpret a missing return value as a pending reply, triggering the blocking behavior.
2. Replace Temporary Channels With a No-Op Reply Channel
Define a dedicated no-op reply channel in your config to prevent the framework from waiting indefinitely for a reply:
@Bean public MessageChannel pubSubNoOpReplyChannel() { return new DirectChannel(); }
Configure your messaging flow to use this channel for Pub/Sub message handling. This tells Spring not to expect a reply, eliminating the thread block.
3. Upgrade Outdated Dependencies (Critical!)
Your dependency versions have known threading bugs in the Pub/Sub integration:
- spring-boot: Upgrade to 2.2.13.RELEASE (latest stable patch for the 2.2.x line)
- springCloudVersion: Move to Greenwich.SR6 (final patch release for Greenwich)
- google-cloud-pubsub: Update to 1.108.0 or higher
Google and Spring fixed several subscriber thread management and reply channel issues in these later versions—this alone might resolve the problem entirely.
4. Validate ACK Handler Asynchronicity
Ensure your MyPubSubAckHandler is fully non-blocking. If ACK processing blocks the subscriber thread, it contributes to pool exhaustion. Use direct Pub/Sub message ack() methods instead of tying ACKs to synchronous messaging flows whenever possible.
Quick Verification Test
Before full upgrades, modify your EmptyNotificationHandler to return null explicitly. If threads stop blocking, this confirms the synchronous reply expectation was the root issue.
内容的提问来源于stack exchange,提问作者gstackoverflow

