Java Spring cloud stream:动态输出通道奇怪的行为
我正在使用SpringCloudStreamVersion2.1.0.RELEASE将消息(在本例中是发送给Kafka)发送到根据接收到的输入动态定义的通道。问题在于,只有每一条消息都会在正确的通道中结束,而另一半则会在默认通道中结束 我用样本作为起点 我将要发送到的通道放入特定的消息头中,然后使用HeaderValueRouter检查相同的头值,以查看要输出到哪个通道 我正在按如下方式配置我的应用程序:Java Spring cloud stream:动态输出通道奇怪的行为,java,spring,spring-integration,spring-cloud-stream,Java,Spring,Spring Integration,Spring Cloud Stream,我正在使用SpringCloudStreamVersion2.1.0.RELEASE将消息(在本例中是发送给Kafka)发送到根据接收到的输入动态定义的通道。问题在于,只有每一条消息都会在正确的通道中结束,而另一半则会在默认通道中结束 我用样本作为起点 我将要发送到的通道放入特定的消息头中,然后使用HeaderValueRouter检查相同的头值,以查看要输出到哪个通道 我正在按如下方式配置我的应用程序: @EnableBinding(CloudStreamConfig.DynamicSourc
@EnableBinding(CloudStreamConfig.DynamicSource.class)
public class CloudStreamConfig {
@Autowired
private BinderAwareChannelResolver resolver;
public static final String CHANNEL_HEADER = "channelHeader";
public static final String OUTPUT_CHANNEL = "outputChannel";
private final String defaultChannel = "defaultChannel";
@ServiceActivator(inputChannel = OUTPUT_CHANNEL)
@Bean
public HeaderValueRouter router() {
HeaderValueRouter router = new HeaderValueRouter(CHANNEL_HEADER);
router.setDefaultOutputChannelName(defaultChannel);
router.setChannelResolver(resolver);
return router;
}
public interface DynamicSource {
@Output(OUTPUT_CHANNEL)
MessageChannel output();
}
}
在我的控制器中,我接收一个对象和一个参数,该参数定义了将其发送到哪个通道,然后将其发送到MessageChannel。相关代码如下:
@Autowired
@Qualifier(CloudStreamConfig.OUTPUT_CHANNEL)
public MessageChannel localChannel;
...
@GetMapping(path = "/error/{channel}")
@ResponseStatus(HttpStatus.OK)
public void error(@PathVariable String channel) {
// build my object
Message message = MessageBuilder.createMessage(myObject,
new MessageHeaders(Collections.singletonMap(CloudStreamConfig.CHANNEL_HEADER, channel)));
localChannel.send(message);
}
如果我向/error/someChannel
发送10条消息,我希望在someChannel
中看到10条消息。但是,我在someChannel
中看到一半消息,而在defaultChannel
中看到另一半消息。我在消息中放入了一个调试计数器变量,它将第一条消息发送到正确的通道,然后每隔一秒将一条消息发送到正确的通道,而其他消息都发送到默认通道
这是什么原因造成的?我如何修复它?我是否误用了我的
DynamicSource
类?我以为它会绑定到任何同名的自动连线MessageChannel
(看起来确实如此),但我想知道我是否遗漏了什么。或者是否存在与BinderAwareChannelResolver
的意外交互?(老实说,我不知道这是干什么用的,我之所以把它包括进来,是因为这些示例是这样做的)输出通道上有两个订户—通道绑定(在绑定器中)和路由器
对于DirectChannel
s,默认的调度算法是循环调度,因此您可以交替向路由器发送消息,也可以直接向绑定器发送消息
对于服务激活器,您需要一个不同的DirectChannel
@Bean
,以便所有消息都到达那里,并在路由后从那里到达绑定器
请参见该示例中的
sourceChannel
。我被您的第一句话弄糊涂了,如果我只创建了路由器,为什么输出通道上还有另一个订户?路由器是否不在输出通道之前的级别,决定输出到哪个通道?另外,当我直接按照示例,使用名为“sourceChannel”的DirectChannel和名为“sourceChannel”的inputChannel的ServiceActivator时,我会得到一个循环依赖项,这就是我尝试上述尝试的原因。它很简单-界面的@EnableBinding
创建一个使用者,而@ServiceActivator
创建第二个使用者。您是否尝试过实际运行该示例?如果得到循环依赖,则在该回购协议中打开一个问题。如果你仍然不知道有什么不同,把你的项目发布到某个地方。我的错误是,按原样运行项目是有效的,不会产生循环依赖关系。然而,只要我尝试将通道和路由器配置提取到一个单独的类中,然后将MessageChannel
注入到其他地方,我就会得到一个循环依赖。我只是通过在一个内部类中配置MessageChannel
来解决这个问题