RabbitMQ 没有向我显示在 Spring 消费者和发布者应用程序中创建的队列和交换

Hai*_*sri 1 java spring rabbitmq docker

我正在尝试使用 RabbitMQ 在春季创建发布者和消费者应用程序。一切工作正常,当发布者发送消息时,消费者接收并成功消费它。但正如您在下图中看到的,RabbitMQ 界面没有向我显示创建的队列和交换。

无需排队

在此输入图像描述

无交换

在此输入图像描述

这是我写的代码:

RABBITMQ 配置(发布者应用程序和消费者应用程序中相同)

package com.example.rabbitmq.springrabbitmqconsumer.configuration;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitMQConfig {

    public static final String ROUTING_A = "routing.A";
    public static final String ROUTING_B = "routing.B";

    //QUEUES
    @Bean
    Queue queueA() {
        return new Queue("queue.A", false);
    }
    @Bean
    Queue queueB() {
        return new Queue("queue.B", false);
    }

    //Direct Exchange
    @Bean
    DirectExchange exchange() {
        return new DirectExchange("exchange.direct");
    }

    //BINDINGS
    @Bean
    Binding bindingA(Queue queueA, DirectExchange exchange) {
        return BindingBuilder.bind(queueA)
                .to(exchange)
                .with(ROUTING_A);
    }
    @Bean
    Binding bindingB(Queue queueB, DirectExchange exchange) {
        return BindingBuilder.bind(queueB)
                .to(exchange)
                .with(ROUTING_B);
    }

    @Bean
    MessageConverter messageConverter() {
        return new Jackson2JsonMessageConverter();
    }

    @Bean
    RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setMessageConverter(messageConverter());
        return rabbitTemplate;
    }
}

Run Code Online (Sandbox Code Playgroud)

消息模型(发布者和消费者应用程序中相同)

package com.example.rabbitmq.springrabbitmqconsumer.model;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
public class Message {

    private int id;
    private String name;
}

Run Code Online (Sandbox Code Playgroud)

消费者控制器

package com.example.rabbitmq.springrabbitmqconsumer.controller;

import com.example.rabbitmq.springrabbitmqconsumer.model.Message;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class Consumer {

    @RabbitListener(queues = "queue.A")
    private void receiveA(Message message) {
        log.info("Message received from queueA -> {}", message);
    }

    @RabbitListener(queues = "queue.B")
    private void receiveB(Message message) {
        log.info("Message received from queueB -> {}", message);
    }
}
Run Code Online (Sandbox Code Playgroud)

出版商控制器

package com.example.rabbitmq.springrabbitmqproducer.contoller;

import com.example.rabbitmq.springrabbitmqproducer.model.Message;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class Producer {

    private final RabbitTemplate rabbitTemplate;

    private final DirectExchange exchange;

    public Producer(RabbitTemplate rabbitTemplate, DirectExchange exchange) {
        this.rabbitTemplate = rabbitTemplate;
        this.exchange = exchange;
    }

    @PostMapping("/posta")
    public String senda(@RequestBody Message message) {
        rabbitTemplate.convertAndSend(exchange.getName(), "routing.A", message);
        return "message sent successfully";
    }

    @PostMapping("/postb")
    public String sendb(@RequestBody Message message) {
        rabbitTemplate.convertAndSend(exchange.getName(), "routing.B", message);
        return "message sent successfully";
    }
}
Run Code Online (Sandbox Code Playgroud)

属性文件(除了端口之外,两个应用程序都相同)

server.port=8081
#rabbitmq configuration
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
Run Code Online (Sandbox Code Playgroud)

这是我用来启动 RabbitMQ 容器的 docker 命令:

docker run -d --name my-rabbit -p 15672:15672 -p 5672:5672 rabbitmq:3-management
Run Code Online (Sandbox Code Playgroud)

可以看到,消费者收到消息并消费 在此输入图像描述

Hai*_*sri 5

我刚刚记得我问过这个问题,但我忘了回答,所以这是解决方案。

我发现我的电脑上安装了rabbitmq,这似乎引起了混乱。因为,Spring 自动运行rabbitmq 实例,就像使用tomcat 一样,所以当我运行rabbitmq docker 镜像时,spring 使用本地实例而不是docker 镜像。

我才意识到,当我将 spring 应用程序进行 dockerized 时,rabbitmq 管理 UI 开始注册队列。

结论
如果你在你的电脑上本地安装了rabbitmq,可能会发生一些情况:

1/非dockeried spring应用程序:工作正常bcz spring将默认使用本地rabbitmq实例,并且您可以打开管理UI

2/dockerized spring应用程序+rabbitmq docker镜像:工作正常,因为当你dockerise你的spring应用程序时,它将停止使用本地实例

3/非dockeried spring应用程序+rabbitmq docker镜像:奇怪的行为,spring会继续将消息推送到队列,但是当你尝试打开管理UI时,你不会看到任何注册的队列,可能是因为这就是管理UI docker 镜像实例

  • 第三种情况发生在我身上,即使从未在设备上安装 RabbitMQ 并且仅使用它抛出 docker (2认同)