Spring Boot Kafka请求-答复方案

时间:2020-09-28 21:21:41

标签: apache-kafka spring-integration spring-kafka spring-cloud-stream

我正在实现请求/答复场景的POC,以便使用Kafka移动基于事件的微服务堆栈。

春季有2种选择。 我想知道哪个更好用。 ReplyingKafkaTemplatecloud-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) {
       .....
}

第二个选项使用StreamListenerspring-integrationIntegrationFlows的组合。应该配置网关并过滤回复主题。

@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

欢迎任何建议。

1 个答案:

答案 0 :(得分:0)

Spring Cloud Stream不适用于请求/答复;这是可以做到的,不是很简单,您必须编写代码。

借助@KafkaListener,框架可以为您处理一切。

如果您也希望它也可以与RabbitMQ一起使用,也可以使用@RabbitListener对其进行注释。