如何在不同的处理程序中处理来自Spring Boot@RabbitListener的消息



我正在尝试使用AMQP和Spring-web为SpringBoot使用请求/响应模式。我有一个客户端服务,它有@RestController和AsyncRabbit配置,有直接交换、路由密钥等,服务器有一个简单的请求队列侦听器
客户端(类似于rest网关控制器(:

@RestController
public class ClientController {
@GetMapping("/test1")
public String getRequest() {
ListenableFuture<String> listenableFuture = asyncRabbitTemplate.convertAndReceiveAsType(
directExchange.getName(),
routingKey,
testDto,
new ParameterizedTypeReference<>() {}
);
return listenableFuture.get(); // Here I receive response from server services
}
@GetMapping("/test2")
public String getRequest2() {
ListenableFuture<String> listenableFuture = asyncRabbitTemplate.convertAndReceiveAsType(
/* Same properties but I use another DTO object for request */
);
return listenableFuture.get()
}

服务器:

@RabbitListener(queues = "#{queue.name}", concurrency = "10")
@Component
public class Consumer {
@RabbitHandler
public String receive(TestDto testDto) {
...
}
@RabbitHandler
public String receive2(AnotherTestDto anotherTestDto) {
...
}
}

我应该如何实现Rabbit监听器来处理每个REST请求
我只找到了两种方法:

  1. 使用@RabbitHandler,如上例所示。但对于每个请求方法(GET、POST等(,我需要唯一的DTO类来发送消息并在正确的处理程序中处理它,即使";请求主体";几乎相同(请求方法的数量=要发送的DTO类的数量(。我不确定这是正确的方式
  2. 留下一个Consumer并调用所需的方法来处理依赖于消息体的消息(如果是其他方法,则是琐碎的(:
...
@RabbitListener(queues = "#{queue.name}")
public String receive(MessageDto messageDto) {
if (messageDto.requestType == "get.method1") {
return serverService.processThat(messageDto);
} else if (messageDto.requestType == "post.method2") {
return serverService.processAnother(messageDto);
} else if ...
...
}
...

但是每次添加新的if else分支不是很方便,所以我真的没办法。

您可以考虑为不同的请求类型使用不同的队列。所有这些都将绑定到同一个直接交换机,但使用各自的路由密钥。

在使用者端,您只需要为相应的队列添加一个新的@RabbitListener。并使用其路由密钥将该队列绑定到交换机。

这实际上就是AMQP protol本身的一个优点:生产者总是用各自的路由密钥发布到同一个交换机。使用者注册其对路由密钥的兴趣并绑定队列。路由逻辑的其余部分在AMQP代理上完成。

查看文档中的更多信息:https://www.rabbitmq.com/tutorials/tutorial-four-spring-amqp.html

最新更新