bigywater.tech
Spring · 147

Spring Integration:消息通道与端点

Spring Integration 的 DirectChannel、QueueChannel、PublishSubscribeChannel 到底差在哪?消息发给谁、在哪个线程执行?处理器抛异常谁能看到?Gateway 的 replyTimeout 为什么没生效?poller 为什么会让消费变慢?这篇在 Spring Integration 7.0.6 上逐项实测。

1505 ms
请求通道是 DirectChannel 时,处理器睡 1.5 秒,replyTimeout 500 ms 的网关调用实际等待的时间,超时没有生效
1566 ms 对 30 ms
PollingConsumer 每次取 1 条与一次取完,6 条消息全部消费完的耗时
后面的收不到
PublishSubscribeChannel 默认第一个订阅者抛异常后,第二个订阅者没有收到消息

DirectChannel

实测 · 本机执行输出
  发 4 条,处理情况(每条只给一个订阅者,轮流;在发送线程里执行):[h1[main]:m1, h2[main]:m2, h1[main]:m3, h2[main]:m4]
  第一个订阅者总是抛异常,默认 failover:[h2:x1, h2:x2, h2:x3]
  setFailover(false):[异常:MessageDeliveryException, h2:x2, 异常:MessageDeliveryException]

点对点轮询,发送线程里执行,默认 failover。

PublishSubscribeChannel

实测 · 本机执行输出
  没有 executor:两个订阅者都收到,都在发送线程里:[a[main], b[main]]
  带 executor:[a[线程池线程], b[线程池线程]]
  第一个订阅者抛异常(ignoreFailures 默认 false):[send 抛出 MessageDeliveryException]

广播;默认一个失败后面不执行。

QueueChannel

实测 · 本机执行输出
  容量 3 的队列已满,send(msg, 0) 返回 false
  send(msg, 500) 阻塞了 504 ms 后返回 false
  receive(0) 取到 q1
  PollingConsumer(每 300 ms 轮询一次、每次最多取 1 条):6 条消息全部消费完用了 1566 ms
  maxMessagesPerPoll=-1(一次取完):6 条全部消费完用了 30 ms

poller 间隔与每次条数决定吞吐。

异常

实测 · 本机执行输出
  DirectChannel:send() 抛给了发送方:MessageDeliveryException → 原因 IllegalStateException
  ExecutorChannel:send() 返回 true,没有抛异常;订阅了 errorChannel 的处理器收到:[MessageDeliveryException←IllegalStateException]

同步通道抛给发送方,异步通道发到 errorChannel。

Gateway

实测 · 本机执行输出
  正常请求:call("hi") = reply:hi
  处理器睡 1.5 秒、replyTimeout 500 ms:call("slow") = reply:slow,调用方等了 1505 ms
  请求通道换成 ExecutorChannel(处理器在别的线程里跑):call("slow") = null,调用方等了 511 ms(replyTimeout 才起作用)
  同一个 ExecutorChannel 网关,正常请求:call("hi") = reply:hi
  处理器抛异常:调用方收到 IllegalStateException,原因 无

同步通道上 replyTimeout 不生效。

IntegrationFlow

实测 · 本机执行输出
  输入 3 12 7 20 5:通过过滤(>5)的被转换后路由到 偶数=[12, 20] 奇数=[7];被过滤丢弃的=[3, 5]

DSL 把过滤、转换、路由写在一个 bean 里。

分步演示

Spring Integration
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / OpenJDK 21.0.12(Homebrew) / Spring Boot 4.0.8(Spring Framework 7.0.9、Tomcat 11.0.24) / Spring Cloud 2025.1.3;用 javac 编译、java 直接运行,依赖由 Maven 从 Maven Central 解析;数字每次运行会有小幅抖动。通道与端点在代码里手工创建(不经过消息中间件);线程名和耗时是一次运行的观察值;Gateway 的两个版本分别用 DirectChannel 与 ExecutorChannel 作为请求通道
    • 没有验证:Spring Integration 的 JDBC / Kafka / AMQP / HTTP 等适配器;Aggregator、Splitter、Resequencer;MessageStore 与持久化队列;FluxMessageChannel 与响应式流;spring.integration.poller.* 的默认值;PriorityChannel;作为 EIP 工具与直接用 Kafka Streams / Camel 的取舍
    京ICP备2026067502号-1京公网安备11010502063487号