Java 配置Spring集成聚合器以组合来自RabbitMq扇出交换的响应
我正在尝试使用Spring集成配置以下内容:Java 配置Spring集成聚合器以组合来自RabbitMq扇出交换的响应,java,rabbitmq,spring-integration,spring-amqp,Java,Rabbitmq,Spring Integration,Spring Amqp,我正在尝试使用Spring集成配置以下内容: 向频道发送消息 将此消息发布到具有n个消费者的rabbit fanout(发布/订阅)交易所 每个使用者都提供一条响应消息 让Spring Integration在将这些响应返回到原始客户端之前聚合这些响应 到目前为止,我对此有一些问题 我使用发布-订阅频道来设置apply sequence=“true”属性,以便设置correlationId、sequenceSize和sequenceNumber属性。这些属性正被DefaultAmqpHeader
apply sequence=“true”
属性,以便设置correlationId、sequenceSize和sequenceNumber属性。这些属性正被DefaultAmqpHeaderMapper
丢弃<代码>调试头名称=[correlationId]将不会被映射apply-sequence=“true”
,并且说只有一个订阅者是非常正确的,即int-amqp:outbound-gateway
<int:publish-subscribe-channel id="output" apply-sequence="true"/>
<int:channel id="reply">
<int:interceptors>
<int:wire-tap channel="logger"/>
</int:interceptors>
</int:channel>
<int:aggregator input-channel="reply" method="combine">
<bean class="example.SimpleAggregator"/>
</int:aggregator>
<int:logging-channel-adapter id="logger" level="INFO"/>
<int:gateway id="senderGateway" service-interface="example.SenderGateway" default-request-channel="output" default-reply-channel="reply"/>
<int-amqp:outbound-gateway request-channel="output"
amqp-template="amqpTemplate" exchange-name="fanout-exchange"
reply-channel="reply"/>
<rabbit:connection-factory id="connectionFactory" />
<rabbit:template id="amqpTemplate" connection-factory="connectionFactory" reply-timeout="-1" />
<rabbit:admin connection-factory="connectionFactory" />
<rabbit:queue name="a-queue"/>
<rabbit:queue name="b-queue"/>
<rabbit:fanout-exchange name="fanout-exchange">
<rabbit:bindings>
<rabbit:binding queue="a-queue" />
<rabbit:binding queue="b-queue" />
</rabbit:bindings>
</rabbit:fanout-exchange>
我的rabbitMQ配置如下:
<int:publish-subscribe-channel id="output" apply-sequence="true"/>
<int:channel id="reply">
<int:interceptors>
<int:wire-tap channel="logger"/>
</int:interceptors>
</int:channel>
<int:aggregator input-channel="reply" method="combine">
<bean class="example.SimpleAggregator"/>
</int:aggregator>
<int:logging-channel-adapter id="logger" level="INFO"/>
<int:gateway id="senderGateway" service-interface="example.SenderGateway" default-request-channel="output" default-reply-channel="reply"/>
<int-amqp:outbound-gateway request-channel="output"
amqp-template="amqpTemplate" exchange-name="fanout-exchange"
reply-channel="reply"/>
<rabbit:connection-factory id="connectionFactory" />
<rabbit:template id="amqpTemplate" connection-factory="connectionFactory" reply-timeout="-1" />
<rabbit:admin connection-factory="connectionFactory" />
<rabbit:queue name="a-queue"/>
<rabbit:queue name="b-queue"/>
<rabbit:fanout-exchange name="fanout-exchange">
<rabbit:bindings>
<rabbit:binding queue="a-queue" />
<rabbit:binding queue="b-queue" />
</rabbit:bindings>
</rabbit:fanout-exchange>
消费者看起来是这样的:
<int:channel id="input"/>
<int-amqp:inbound-gateway request-channel="input" queue-names="a-queue" connection-factory="connectionFactory" concurrent-consumers="1"/>
<bean id="listenerService" class="example.ListenerService"/>
<int:service-activator input-channel="input" ref="listenerService" method="receiveMessage"/>
任何建议都很好,我怀疑我在某个地方弄错了方向
基于Gary评论的新出站spring配置:
<int:channel id="output"/>
<int:header-enricher input-channel="output" output-channel="output">
<int:correlation-id expression="headers['id']" />
</int:header-enricher>
<int:gateway id="senderGateway" service-interface="example.SenderGateway" default-request-channel="output" default-reply-timeout="5000" default-reply-channel="reply" />
<int-amqp:outbound-gateway request-channel="output"
amqp-template="amqpTemplate" exchange-name="fanout-exchange"
reply-channel="reply"
mapped-reply-headers="amqp*,correlationId" mapped-request-headers="amqp*,correlationId"/>
<int:channel id="reply"/>
<int:aggregator input-channel="reply" output-channel="reply" method="combine" release-strategy-expression="size() == 2">
<bean class="example.SimpleAggregator"/>
</int:aggregator>
问题是S.I.不知道扇出交换机的拓扑结构 解决这个问题的最简单方法是使用自定义发布策略
release-strategy-expression="size() == 2"
在聚合器上(假设扇出为2)。因此,您不需要序列大小;您可以使用标题充实器避免“滥用”发布/订阅频道
<int:header-enricher input-channel="foo" output-channel="bar">
<int:correlation-id expression="T(java.util.UUID).randomUUID().toString()" />
</int:header-enricher>
到您的amqp端点。即使这个问题已经3年了,我还是要回答它,因为我有同样的问题 SpringIntegration的一个实现听起来很像您最初的问题 以下是来自 它是一个复合端点,目标是向 收件人并聚合结果 以前,模式可以使用离散组件进行配置, 此增强带来了更方便的配置 ScatterGatherHandler是一个请求-应答端点,它结合了 PublishSubscribeChannel(或RecipientListRouter)和 聚合MessageHandler。请求消息将被发送到分散服务器 通道和ScatterGatherHandler等待来自 要发送到outputChannel的聚合器
谢谢Gary,这让我走得更远了,现在的问题是我的出站网关似乎没有等待消息的响应。消费者可以很好地(从扇出交换)接收消息,我可以看到他们都在回复同一个rabbitmq队列(从调试),但我没有从发送者那里收到回复。我必须将amqp*添加到mapped request headers属性中,否则标准amqp标头将丢失。我没有注意到您正在使用网关-网关只处理对请求的单个答复。您需要使用出站适配器发送请求,使用入站适配器接收回复。您需要手动填充标头,以便2个使用者上的入站网关知道如何回复。