SpringBoot integrates RabbitMQ (basic)

1. Environmental preparation

1. Introduce the corresponding dependencies into the pom file:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

2. Configure RabbitMQ in the application.yml configuration file:

spring:
    #rabbitmq配置
  rabbitmq:
    host: 192.168.150.152#rabbitMq的服务器地址
    port: 5672
    username: root #用户名
    password: 123456 #密码
    virtual-host: /hjl #虚拟主机

2. Integration

  1. Point-to-point, simple mode
    Insert image description here
    ① Declare the queue in the configuration file
@SpringBootConfiguration
public class RabbitMqConfig {
    
    
    /**
     * hello队列名称
     */
    public static final String HELLO_MSG_QUEUE = "hello.msg.queue";
   
    /**
     * 声明hello队列
     *
     * @return
     */
    @Bean
    public Queue getHelloQueue() {
    
    
    	//参数一:队列名;参数二:是否持久化队列
        return new Queue(HELLO_MSG_QUEUE, true);
    }


}

②Create a producer

@SpringBootTest
@RunWith(SpringRunner.class)
public class RabbitMqTest {
    
    
    @Resource
    private RabbitTemplate rabbitTemplate;
    @Test
    public void sendHello() {
    
    
        for (int i = 0; i < 10; i++) {
    
    
            rabbitTemplate.convertAndSend(RabbitMqConfig.HELLO_MSG_QUEUE, "hello world" + i);
        }
    }
}

After the message is sent successfully, check it on the web management page: Insert image description here
you can see that the message is generated in the corresponding queue
③ Create a consumer

@Component
public class RabbitMqConsumer {
    
    
    @RabbitListener(queues = RabbitMqConfig.HELLO_MSG_QUEUE)
    public void listenHelloMsg(String message) {
    
    
        System.out.println("接受时间:"+System.currentTimeMillis());
        System.out.println("转发消息是:" + message);
    }
}

Start the project and you can see that the message is successfully consumed:
Insert image description here

  1. Work queue (multiple consumers correspond to one queue)
    Insert image description here
    ①Declare the queue
@SpringBootConfiguration
public class RabbitMqConfig {
    
    
    /**
     * work队列名称
     */
    public static final String WORK_MSG_QUEUE = "work.msg.queue";
    /**
     * 声明work队列
     *
     * @return
     */
    @Bean
    public Queue getWorkQueue() {
    
    
        //参数一:队列名;参数二:是否持久化队列
        return new Queue(WORK_MSG_QUEUE, true);
    }
}

②Create a producer

@SpringBootTest
@RunWith(SpringRunner.class)
public class WorkMqTest {
    
    
    @Resource
    private RabbitTemplate rabbitTemplate;

    @Test
    public void send() {
    
    
        for (int i = 0; i < 10; i++) {
    
    
            rabbitTemplate.convertAndSend(RabbitMqConfig.WORK_MSG_QUEUE, "这是一条工作队列消息" + i);
        }
    }
}

③Create consumers (multiple)

@Component
public class RabbitMqConsumer {
    
    
    @RabbitListener(queues = RabbitMqConfig.WORK_MSG_QUEUE)
    public void listenWork1(String message) {
    
    
        System.out.println("消费者一转发消息是:" + message);
    }
    @RabbitListener(queues = RabbitMqConfig.WORK_MSG_QUEUE)
    public void listenWork2(String message) {
    
    
        System.out.println("消费者二转发消息是:" + message);
    }
}

Insert image description here
You can see that both consumers successfully consumed the messages in the word queue.

  1. Publish and subscribe mode
    Insert image description here
    ① declare queue, switch and bind

@SpringBootConfiguration
public class RabbitMqConfig {
    
    
   /**
     * publish队列1
     */
    public static final String PUBLISH_MSG_QUEUE1 = "publish.msg.queue1";
    /**
     * publish队列2
     */
    public static final String PUBLISH_MSG_QUEUE2 = "publish.msg.queue2";
    /**
     * publish交换机
     */
    public static final String PUBLISH_EXCHANGE = "publish.exchange";

   
    /**
     * Publish队列
     *
     * @return
     */
    @Bean
    public Queue getPublishQueue1() {
    
    
        return new Queue(PUBLISH_MSG_QUEUE1, true);
    }
    /**
     * Publish队列
     *
     * @return
     */
    @Bean
    public Queue getPublishQueue2() {
    
    
        return new Queue(PUBLISH_MSG_QUEUE2, true);
    }
    /**
     * Publish交换机
     *
     * @return
     */
    @Bean
    public FanoutExchange publishExchange() {
    
    
        FanoutExchange exchange = new FanoutExchange(PUBLISH_EXCHANGE, true, false);
        return exchange;
    }

    /**
     * 绑定队列和交换机
     *
     * @return
     */
    @Bean
    public Binding bindPublishExchangeQueue1() {
    
    
        Binding binding = BindingBuilder.bind(getPublishQueue1()).to(publishExchange());
        return binding;
    }
    /**
     * 绑定队列和交换机
     *
     * @return
     */
    @Bean
    public Binding bindPublishExchangeQueue2() {
    
    
        Binding binding = BindingBuilder.bind(getPublishQueue2()).to(publishExchange());
        return binding;
    }

②Create a producer

@SpringBootTest
@RunWith(SpringRunner.class)
public class PublishMqTest {
    
    
    @Resource
    private RabbitTemplate rabbitTemplate;

    @Test
    public void send() {
    
    
        for (int i = 0; i < 10; i++) {
    
    
            //参数一:交换机名称;参数二:routingKey(广播模式不传);参数三:消息体
            rabbitTemplate.convertAndSend(RabbitMqConfig.PUBLISH_EXCHANGE, null, "这是一条工作队列消息" + i);
        }
    }
}

③Create consumers (multiple)

@Component
public class PublishConsumer {
    
    
    @RabbitListener(queues = RabbitMqConfig.PUBLISH_MSG_QUEUE1)
    public void listenDead1(String message) {
    
    
        System.out.println("消费者一接收消息:" + message);
    }
    @RabbitListener(queues = RabbitMqConfig.PUBLISH_MSG_QUEUE2)
    public void listenDead2(String message) {
    
    
        System.out.println("消费者二接收消息:" + message);
    }
}

Insert image description here
It can be seen that the two consumption centers receive all the messages from the producer; unlike the work queue, the consumer of the work queue only consumes some messages, while this mode consumes all messages.

  1. routing mode

Insert image description here
①Declare the queue


@SpringBootConfiguration
public class RabbitMqConfig {
    
    
   
    /**
     * routing交换机
     */
    public static final String ROUTING_EXCHANGE = "routing.exchange";
    /**
     * routing队列1
     */
    public static final String ROUTING_MSG_QUEUE1 = "routing.msg.queue1";
    /**
     * routing队列2
     */
    public static final String ROUTING_MSG_QUEUE2 = "routing.msg.queue2";

    /**
     * routing队列
     *
     * @return
     */
    @Bean
    public Queue getRoutingQueue1() {
    
    
        return new Queue(ROUTING_MSG_QUEUE1, true);
    }

    /**
     * routing队列
     *
     * @return
     */
    @Bean
    public Queue getRoutingQueue2() {
    
    
        return new Queue(ROUTING_MSG_QUEUE2, true);
    }

    /**
     * Publish交换机
     *
     * @return
     */
    @Bean
    public DirectExchange routingExchange() {
    
    
        DirectExchange exchange = new DirectExchange(ROUTING_EXCHANGE, true, false);
        return exchange;
    }

    /**
     * 绑定队列和交换机
     *
     * @return
     */
    @Bean
    public Binding bindRoutingExchangeQueue1() {
    
    
        Binding binding = BindingBuilder.bind(getRoutingQueue1()).to(routingExchange()).with("routingKey1");
        return binding;
    }

    /**
     * 绑定队列和交换机
     *
     * @return
     */
    @Bean
    public Binding bindRoutingExchangeQueue2() {
    
    
        Binding binding = BindingBuilder.bind(getRoutingQueue2()).to(routingExchange()).with("routingKey2");
        return binding;
    }
}

②Create a producer

@SpringBootTest
@RunWith(SpringRunner.class)
public class RoutingMqTest {
    
    
    @Resource
    private RabbitTemplate rabbitTemplate;

    @Test
    public void send() {
    
    
            //参数一:交换机名称;参数二:routingKey(交换机与队列绑定的key);参数三:消息体
            rabbitTemplate.convertAndSend(RabbitMqConfig.ROUTING_EXCHANGE, "routingKey1", "队列一:这是一条路由消息消息");
            rabbitTemplate.convertAndSend(RabbitMqConfig.ROUTING_EXCHANGE, "routingKey2", "队列二:这是一条路由消息消息");
    }
}

③Create consumers

@Component
public class RoutingConsumer {
    
    
    @RabbitListener(queues = RabbitMqConfig.ROUTING_MSG_QUEUE1)
    public void listenDead1(String message) {
    
    
        System.out.println("消费者一接收消息:" + message);
    }

    @RabbitListener(queues = RabbitMqConfig.ROUTING_MSG_QUEUE2)
    public void listenDead2(String message) {
    
    
        System.out.println("消费者二接收消息:" + message);
    }
}

Running results:
Insert image description here
x is obvious: unlike the publish-subscribe mode, this mode requires the switch and queue to be bound through routingKey, and the producer can send messages to the specified queue by specifying routingKey.

  1. Wildcard mode
    Insert image description here
    ① declare queue, switch

@SpringBootConfiguration
public class RabbitConfig {
    
    

    /**
     * topic交换机
     */
    public static final String TOPIC_EXCHANGE = "topic.exchange";
    /**
     * topic队列1
     */
    public static final String TOPIC_MSG_QUEUE1 = "topic.msg.queue1";
    /**
     *topic队列2
     */
    public static final String TOPIC_MSG_QUEUE2 = "topic.msg.queue2";

    /**
     * routing队列
     *
     * @return
     */
    @Bean
    public Queue getTopicQueue1() {
    
    
        return new Queue(TOPIC_MSG_QUEUE1, true);
    }
    /**
     * routing队列
     *
     * @return
     */
    @Bean
    public Queue getTopicQueue2() {
    
    
        return new Queue(TOPIC_MSG_QUEUE2, true);
    }
    /**
     * Publish交换机
     *
     * @return
     */
    @Bean
    public TopicExchange topIcExchange() {
    
    
        TopicExchange exchange = new TopicExchange(TOPIC_EXCHANGE, true, false);
        return exchange;
    }

    /**
     * 绑定队列和交换机
     *
     * @return
     */
    @Bean
    public Binding bindTopicExchangeQueue1() {
    
    
        Binding binding = BindingBuilder.bind(getTopicQueue1()).to(topIcExchange()).with("topKey.*");
        return binding;
    }
    /**
     * 绑定队列和交换机
     *
     * @return
     */
    @Bean
    public Binding bindTopicExchangeQueue2() {
    
    
        Binding binding = BindingBuilder.bind(getTopicQueue2()).to(topIcExchange()).with("topKey.#");
        return binding;
    }
}

②Create a producer

@SpringBootTest
@RunWith(SpringRunner.class)
public class TopicMqTest {
    
    
    @Resource
    private RabbitTemplate rabbitTemplate;

    @Test
    public void send() {
    
    
        //参数一:交换机名称;参数二:routingKey(广播模式不传);参数三:消息体
        rabbitTemplate.convertAndSend(RabbitConfig.TOPIC_EXCHANGE, "topic.key1", "这是一条通配符模式消息一");
        rabbitTemplate.convertAndSend(RabbitConfig.TOPIC_EXCHANGE, "topic.key1.key2", "这是一条通配符模式消息二");
    }
}

③Create consumers

@Component
public class TopicConsumer {
    
    
    @RabbitListener(queues = RabbitConfig.TOPIC_MSG_QUEUE1)
    public void listenDead1(String message) {
    
    
        System.out.println("消费者一接收消息:" + message);
    }

    @RabbitListener(queues = RabbitConfig.TOPIC_MSG_QUEUE2)
    public void listenDead2(String message) {
    
    
        System.out.println("消费者二接收消息:" + message);
    }
}

The running results are as follows:
Insert image description here
You can see that: different from the routing mode, topic supports routing keys in wildcard mode; in particular, "*" can only replace one word; and "#" can replace multiple;

Guess you like

Origin blog.csdn.net/asasasasasawqwqwqw/article/details/131096637