我们正在设计一个微服务架构,我们希望将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);
}
欢迎任何帮助。
答案 0 :(得分:1)
你的绑定没有意义;第一个匹配所有密钥的格式为foo.bar
,baz.qux
等,因此第二个密钥无关紧要。
你应该只是为事件使用扇出交换,每个服务有2个队列,一个在扇出事件上,另一个在主题交换作业(对于自己的工作只有一个狭窄的绑定)。