如何使用RabbitMQ订阅特定的路由密钥

时间:2018-03-29 14:56:07

标签: spring rabbitmq microservices spring-amqp

我们正在设计一个微服务架构,我们希望将RabbitMQ用作消息代理。

我们希望每项服务都有一个特定的队列,比方说applicationQueue

我们还定义了我们的消息有两种:

事件:路由到每个服务的邮件。如果服务对某些特定事件感兴趣,它将拦截它并从中创建任务

任务:表示从服务创建给自己的作业的消息,它们应该只发布到服务本身的队列

到目前为止,我们正在努力使用Spring AMQP来实现它。

我们设计了一个消息生成器,因此在给定的http请求之后,它将为服务本身创建一个任务:

RestController:

@PostMapping
public void saveProduct(@RequestBody Product product) {
    messageProducer.message("subscriptions.product.create", product)
            .fromHttpRequest(requestContext)
            .send();
}

我们的消息生产者的发送方法:

public void send() {
        template.convertAndSend(exchange, routingKey, payload, message -> {
            if (requestContext != null) {
                extractHttpRequestInfo(message);
                message.getMessageProperties().getHeaders()
                        .put(MessageDictionary.TRANSACTION_ID, generateTransactionId());
            } else if (originalMessage != null) {
                extractMessageInfo(message);
            }
            return message;
        });
    }

RabbitMQ配置:

@Bean
List<Binding> binding(Queue queue, TopicExchange exchange) {
    return Arrays.asList(
            BindingBuilder.bind(queue).to(exchange).with("*.*"),
            BindingBuilder.bind(queue).to(exchange).with("${condohub.rabbitmq.queue.name}.#")
    );
}

然后在其他地方订阅(@Digest注释是自定义注释):

@Digest("${condohub.rabbitmq.queue.name}.product.create")
public void createProduct(Product product) {
    service.save(product);
}

欢迎任何帮助。

1 个答案:

答案 0 :(得分:1)

你的绑定没有意义;第一个匹配所有密钥的格式为foo.barbaz.qux等,因此第二个密钥无关紧要。

你应该只是为事件使用扇出交换,每个服务有2个队列,一个在扇出事件上,另一个在主题交换作业(对于自己的工作只有一个狭窄的绑定)。