我有一个应用程序(如微服务),该应用应该从其他应用程序(微服务)发送和接收消息。该应用程序有多个发布者,每个发布者都发布到一个特定的队列,还有几个订阅者类,每个订阅者只订阅一个队列。不幸的是,我的订户类正在消耗与我发布的消息相同的消息。我该怎么办?
这是我的代码: a)发布者1-没有侦听器方法,因为它仅发布到my.queues.queue1
@Configuration
public class RabbitQueue1Publisher{
private static final String QUEUE_NAME = "my.queues.queue1";
@Bean
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory("http://127.0.0.1:1675");
connectionFactory.setUsername("guest");
connectionFactory.setPassword("guest");
return connectionFactory;
}
@Bean
public Queue simpleQueue() {
return new Queue(QUEUE_NAME);
}
@Bean
public MessageConverter jsonMessageConverter(){
return new Jackson2JsonMessageConverter();
}
@Bean
public RabbitTemplate rabbitTemplate() {
RabbitTemplate template = new RabbitTemplate(connectionFactory());
template.setRoutingKey(QUEUE_NAME);
template.setMessageConverter(jsonMessageConverter());
return template;
}
}
b)Publisher 2-也没有侦听器方法,因为它仅发布到my.queues.queue2
@Configuration
public class RabbitQueue2Publisher{
private static final String QUEUE_NAME = "my.queues.queue2";
@Bean
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory("http://127.0.0.1:1675");
connectionFactory.setUsername("guest");
connectionFactory.setPassword("guest");
return connectionFactory;
}
@Bean
public Queue simpleQueue() {
return new Queue(QUEUE_NAME);
}
@Bean
public MessageConverter jsonMessageConverter(){
return new Jackson2JsonMessageConverter();
}
@Bean
public RabbitTemplate rabbitTemplate() {
RabbitTemplate template = new RabbitTemplate(connectionFactory());
template.setRoutingKey(QUEUE_NAME);
template.setMessageConverter(jsonMessageConverter());
return template;
}
}
c)使用者1-从队列3进行消费。有一个监听方法
@Configuration
public class RabbitQueue3Subscriber{
private static final String QUEUE_NAME = "my.queue.queue3";
@Autowired
private Queue3Listener Queue3Listener;
@Bean
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory("http://127.0.0.1:15672");
connectionFactory.setUsername("guest");
connectionFactory.setPassword("guest");
return connectionFactory;
}
@Bean
public Queue simpleQueue() {
return new Queue(QUEUE_NAME);
}
@Bean
public MessageConverter jsonMessageConverter(){
return new Jackson2JsonMessageConverter();
}
@Bean
public RabbitTemplate rabbitTemplate() {
RabbitTemplate template = new RabbitTemplate(connectionFactory());
template.setRoutingKey(QUEUE_NAME);
template.setMessageConverter(jsonMessageConverter());
return template;
}
@Bean
public SimpleMessageListenerContainer userListenerContainer() {
SimpleMessageListenerContainer listenerContainer = new SimpleMessageListenerContainer();
listenerContainer.setConnectionFactory(connectionFactory());
listenerContainer.setQueues(simpleQueue());
listenerContainer.setMessageConverter(jsonMessageConverter());
listenerContainer.setMessageListener(Queue3Listener);
listenerContainer.setAcknowledgeMode(AcknowledgeMode.AUTO);
return listenerContainer;
}
}
d)消费者2-从队列4消费。有一个监听方法
@Configuration
public class RabbitQueue4Subscriber{
private static final String QUEUE_NAME = "my.queue.queue4";
@Autowired
private Queue4Listener Queue4Listener;
@Bean
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory("http://127.0.0.1:15672");
connectionFactory.setUsername("guest");
connectionFactory.setPassword("guest");
return connectionFactory;
}
@Bean
public Queue simpleQueue() {
return new Queue(QUEUE_NAME);
}
@Bean
public MessageConverter jsonMessageConverter(){
return new Jackson2JsonMessageConverter();
}
@Bean
public RabbitTemplate rabbitTemplate() {
RabbitTemplate template = new RabbitTemplate(connectionFactory());
template.setRoutingKey(QUEUE_NAME);
template.setMessageConverter(jsonMessageConverter());
return template;
}
@Bean
public SimpleMessageListenerContainer userListenerContainer() {
SimpleMessageListenerContainer listenerContainer = new SimpleMessageListenerContainer();
listenerContainer.setConnectionFactory(connectionFactory());
listenerContainer.setQueues(simpleQueue());
listenerContainer.setMessageConverter(jsonMessageConverter());
listenerContainer.setMessageListener(Queue4Listener);
listenerContainer.setAcknowledgeMode(AcknowledgeMode.AUTO);
return listenerContainer;
}
}
尽管我正在向不同队列发布和使用不同队列,但最终还是消耗了我产生的相同消息。有人可以指出我做错了什么或提出解决方法吗?
答案 0 :(得分:0)
这是对我有用的方法。我有Rabbitmq的发行商和消费者。如果它们是同一项目或不同项目的一部分,则不重要。
发布者:
发布者配置
@Configuration
class PublisherConfig{
String queueName = "com.queueName";
String routingKey = "com.routingKey";
String exchange = "com.exchangeName";
@Bean
Queue queue() {
return new Queue(queueName, false);
}
@Bean
TopicExchange exchange() {
return new TopicExchange(exchange);
}
@Bean
Binding binding(Queue queueFoo, TopicExchange exchange) {
return BindingBuilder.bind(queueFoo).to(exchange).with(routingKey);
}
//Required only if you want to pass custom object as part of payload
@Bean
public MappingJackson2MessageConverter jackson2Converter() {
return new MappingJackson2MessageConverter();
}
}
发布消息
@Autowired private RabbitMessagingTemplate rabbitMessagingTemplate;
@Autowired private MappingJackson2MessageConverter mappingJackson2MessageConverter;
rabbitMessagingTemplate.setMessageConverter(this.mappingJackson2MessageConverter);
rabbitMessagingTemplate.convertAndSend(exchange, routingKey, employObj)
消费者
消费者配置
@Configuration
public class RabbitMQConfiguration implements RabbitListenerConfigurer {
public MappingJackson2MessageConverter jackson2Converter() {
return new MappingJackson2MessageConverter();
}
@Bean
public DefaultMessageHandlerMethodFactory handlerMethodFactory() {
DefaultMessageHandlerMethodFactory factory = new DefaultMessageHandlerMethodFactory();
factory.setMessageConverter(jackson2Converter());
return factory;
}
@Override
public void configureRabbitListeners(RabbitListenerEndpointRegistrar registrar) {
registrar.setMessageHandlerMethodFactory(handlerMethodFactory());
}
}
听一条消息
@RabbitListener(queues = "com.queueName")
public void receiveMessage(Employee employee) {
// More code
}
您可以将Publisher和Listener配置封装在两个不同的@configuration文件中。
希望这对您有帮助
P.S。 OP要求解释。在这里:
交换和路由密钥
发布者将消息发布到具有特定exchange
的{{1}}。路由键有助于区分消息的类型。
假设:
发送所有用户登录消息,路由键为“ user_logged_in”。
使用“ email_sent”发送所有通过电子邮件发送的消息。
队列:
一旦路由密钥与交换机绑定,就会出现队列。 队列附加了交换和路由密钥,所有已发布的消息都将位于此队列中。
现在,消费者明确地连接到此类队列并监听消息。
因此,发布者配置和使用者配置中的队列名称必须相同。
发布商启动后,您实际上可以访问RabbitMq仪表板 并查看交换,路由键和队列以了解其工作原理。