Http请求上的Spring Kafka侦听器

时间:2019-01-03 15:39:38

标签: java spring apache-kafka spring-kafka

我正在使用Spring和Kafka,我发出了一个HTTP POST请求,如下所示,并通过Kafka主题将一些信息发送到另一个服务。

@RequestMapping(method = RequestMethod.POST, value = "/portfolio")
public void getPortfolio(
       Authentication auth,
    @RequestBody User user
) {
    //Data Transfer Object
    UserDTO dto = user.toDTO();
    dto.setId(((AuthenticatedUser) auth.getPrincipal()).getId());

    //Sending message to Kafka topic
    sender.sendPortfolioRequest(dto);
}

然后,我想侦听其他主题的响应,并在HTTP响应中返回数据,但是卡在这里。我可以使用以下侦听器方法侦听响应,但不知道如何将两者放在一起。

@KafkaListener(
    topics = Topics.PORTFOLIO_RESULT,
    containerFactory = "portfolioKafkaListenerContainerFactory"
)
public void portfolioListener(UserPortfolioDTO portfolio) {
    System.out.println("Recieved Portfolio: " + portfolio.toString());
}

P.S。我不熟悉使用HTTP请求,并且不知道这是否是执行我要实现的目标的正确方法,或者是否应该使用POST创建新资源并重定向到该资源或其他东西。

2 个答案:

答案 0 :(得分:3)

@KafkaListener无法完成此操作,因为它是单独启动的,并且可以在其自己的线程中完全工作。同时,您希望在HTTP请求线程中得到答复。

这里唯一可行的解​​决方案是ConsumerFactory和Apache Kafka Consumer的手动使用。因此,发送后,您从工厂获得了一个Consumer实例,称其poll()被阻止直到结果,为HTTP建立响应并关闭Consumer

答案 1 :(得分:1)

根据我的理解,我建议您启用asych http请求以能够链接您的进程。

Creating Asynchronous Methods with springboot

此选项将允许您处理sendPortfolioRequest并释放http请求(否则,客户端将发出http请求超时)。

您尝试做的事情看起来像是反模式:您想链接一个sychron http请求(因为您的http客户端正在等待服务器的响应)和一个异步消息传递系统(Kafka)。

为了能够做您想做的事情,建议您更改http端点并添加一个websocket,以实现最佳实践。

请参阅Using WebSocket to build an interactive web application