我正在实现请求/答复场景的POC,以便使用Kafka移动基于事件的微服务堆栈。
春季有2种选择。
我想知道哪个更好用。 ReplyingKafkaTemplate
或cloud-stream
首先是ReplyingKafkaTemplate
,可以很容易地将其配置为具有专用通道以答复每个实例的主题。
record.headers().add(new RecordHeader(KafkaHeaders.REPLY_TOPIC, provider.getReplyChannelName().getBytes()));
消费者不需要知道答复主题的名称,只需听一个主题并返回给定的答复主题即可。
@KafkaListener(topics = "${kafka.topic.concat-request}")
@SendTo
public ConcatReply listen(ConcatModel request) {
.....
}
第二个选项使用StreamListener
,spring-integration
和IntegrationFlows
的组合。应该配置网关并过滤回复主题。
@MessagingGateway
public interface StreamGateway {
@Gateway(requestChannel = START, replyChannel = FILTER, replyTimeout = 5000, requestTimeout = 2000)
String process(String payload);
}
@Bean
public IntegrationFlow headerEnricherFlow() {
return IntegrationFlows.from(START)
.enrichHeaders(HeaderEnricherSpec::headerChannelsToString)
.enrichHeaders(headerEnricherSpec -> headerEnricherSpec.header(Channels.INSTANCE_ID ,instanceUUID))
.channel(Channels.REQUEST)
.get();
}
@Bean
public IntegrationFlow replyFiltererFlow() {
return IntegrationFlows.from(GatewayChannels.REPLY)
.filter(Message.class, message -> Channels.INSTANCE_ID.equals(message.getHeaders().get("instanceId")) )
.channel(FILTER)
.get();
}
建筑回复
@StreamListener(Channels.REQUEST)
@SendTo(Channels.REPLY)
public Message<?> process(Message<String> request) {
必须指定回复渠道。因此,接收到的回复主题会根据instanceID进行过滤,这是一种解决方法(可能会使网络膨胀)。另一方面,通过添加启用DLQ场景
consumer:
enableDlq: true
就与RabbitMQ和其他功能的互操作性而言,使用Spring Cloud Streams看起来很有希望,但并未立即正式支持请求回复方案。问题仍未解决,也不被拒绝。 (https://github.com/spring-cloud/spring-cloud-stream/issues/1800)
欢迎任何建议。
答案 0 :(得分:0)
Spring Cloud Stream不适用于请求/答复;这是可以做到的,不是很简单,您必须编写代码。
借助@KafkaListener
,框架可以为您处理一切。
如果您也希望它也可以与RabbitMQ一起使用,也可以使用@RabbitListener
对其进行注释。