RabbitMQ - Spring Boot

江枫思渺然 提交于 2020-02-02 04:03:16

Introduction

RabbitMQ是一个消息代理:它接受并转发消息.你可以把它当成一个邮局:当你想邮寄信件的时候,你会把信件放在投递箱中,并确信邮递员最终会将信件送到收件人的手里.在这个例子中,RabbitMQ就相当与投递箱,邮局和邮递员.

AMQP协议中的核心思想就是生产者和消费者隔离,生产者从不直接将消息发送给队列.生产者通常不知道是否一个消息会被发送到队列中,只是将消息发送到一个交换机.先由Exchange来接收,然后Exchange按照特定的策略转发到Queue进行存储.同理,消费者也是如此.Exchange 就类似于一个交换机,转发各个消息分发到相应的队列中.

RabbitMQ Work Mode

在这里插入图片描述

Direct – 路由模式

直连型交换机,根据消息携带的路由键将消息投递给对应队列

大致流程,有一个队列绑定到一个直连交换机上,同时赋予一个路由键 routing key.
然后当一个消息携带着路由值为X,这个消息通过生产者发送给交换机时,交换机就会根据这个路由值X去寻找绑定值也是X的队列.

RabbitMQ direct producer

application.properties

server.port= 8021
spring.application.name= rabbitmq-provider
spring.rabbitmq.host= 127.0.0.1
spring.rabbitmq.port= 5672
spring.rabbitmq.username= guest
spring.rabbitmq.password= guest

pom.xml

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

		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
	</dependencies>

DirectRabbitConfig.java

package com.dudu.rabbitmq_direct;

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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class DirectRabbitConfig {
    @Bean
    public Queue TestDirectQueue() {
        return new Queue("TestDirectQueue", true);
    }

    @Bean
    DirectExchange TestDirectExchange() {
        return new DirectExchange("TestDirectExchange");
    }

    @Bean
    Binding bindingDirect() {
        return BindingBuilder.bind(TestDirectQueue()).to(TestDirectExchange()).with("TestDirectRouting");
    }
}

SendMessageController.java

package com.dudu.rabbitmq_direct;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@RestController
public class SendMessageController {
    @Autowired
    RabbitTemplate rabbitTemplate;

    @GetMapping("/sendDirectMessage")
    public String sendDirectMessage() {
        String messageId = String.valueOf(UUID.randomUUID());
        String messageData = "test message, hello!";
        String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        Map<String, Object> map = new HashMap<>();
        map.put("messageId", messageId);
        map.put("messageData", messageData);
        map.put("createTime", createTime);
        rabbitTemplate.convertAndSend("TestDirectExchange", "TestDirectRouting", map);
        return "ok";
    }
}

Console Output

2020-01-31 19:45:19.482  INFO 5662 --- [           main] c.d.r.RabbitmqDirectApplication          : Starting RabbitmqDirectApplication on hugh-virtual-machine with PID 5662 (/home/hugh/IdeaProjects/rabbitmq/target/classes started by hugh in /home/hugh/IdeaProjects/rabbitmq)
2020-01-31 19:45:19.492  INFO 5662 --- [           main] c.d.r.RabbitmqDirectApplication          : No active profile set, falling back to default profiles: default
2020-01-31 19:45:20.413  INFO 5662 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8021 (http)
2020-01-31 19:45:20.421  INFO 5662 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2020-01-31 19:45:20.423  INFO 5662 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.30]
2020-01-31 19:45:20.477  INFO 5662 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2020-01-31 19:45:20.477  INFO 5662 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 912 ms
2020-01-31 19:45:20.679  INFO 5662 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2020-01-31 19:45:20.848  INFO 5662 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8021 (http) with context path ''
2020-01-31 19:45:20.851  INFO 5662 --- [           main] c.d.r.RabbitmqDirectApplication          : Started RabbitmqDirectApplication in 1.808 seconds (JVM running for 2.141)
2020-01-31 19:45:27.596  INFO 5662 --- [nio-8021-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-01-31 19:45:27.597  INFO 5662 --- [nio-8021-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2020-01-31 19:45:27.603  INFO 5662 --- [nio-8021-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 6 ms
2020-01-31 19:45:27.638  INFO 5662 --- [nio-8021-exec-2] o.s.a.r.c.CachingConnectionFactory       : Attempting to connect to: [127.0.0.1:5672]
2020-01-31 19:45:27.776  INFO 5662 --- [nio-8021-exec-2] o.s.a.r.c.CachingConnectionFactory       : Created new connection: rabbitConnectionFactory#28f8e165:0/SimpleConnection@6a318c5f [delegate=amqp://guest@127.0.0.1:5672/, localPort= 43882]

RabbitMQ direct consumer

application.properties

server.port= 8022
spring.application.name= rabbitmq-consumer
spring.rabbitmq.host= 127.0.0.1
spring.rabbitmq.port= 5672
spring.rabbitmq.username= guest
spring.rabbitmq.password= guest

pom.xml

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

		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
	</dependencies>

DirectReceiver.java

package com.dudu.rabbitmq_consumer;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.util.Map;

@Component
@RabbitListener(queues = "TestDirectQueue")
public class DirectReceiver {
    @RabbitHandler
    public void process(Map message) {
        System.out.println("DirectReceiver message:" + message.toString());
    }
}

Console Output

2020-01-31 19:53:48.694  INFO 6386 --- [           main] c.d.rabbitmq_consumer.DemoApplication    : Starting DemoApplication on hugh-virtual-machine with PID 6386 (/home/hugh/IdeaProjects/rabbitmq_consumer/target/classes started by hugh in /home/hugh/IdeaProjects/rabbitmq_consumer)
2020-01-31 19:53:48.703  INFO 6386 --- [           main] c.d.rabbitmq_consumer.DemoApplication    : No active profile set, falling back to default profiles: default
2020-01-31 19:53:49.792  INFO 6386 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8022 (http)
2020-01-31 19:53:49.802  INFO 6386 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2020-01-31 19:53:49.802  INFO 6386 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.30]
2020-01-31 19:53:49.876  INFO 6386 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2020-01-31 19:53:49.876  INFO 6386 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1126 ms
2020-01-31 19:53:50.032  INFO 6386 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2020-01-31 19:53:50.265  INFO 6386 --- [           main] o.s.a.r.c.CachingConnectionFactory       : Attempting to connect to: [127.0.0.1:5672]
2020-01-31 19:53:50.329  INFO 6386 --- [           main] o.s.a.r.c.CachingConnectionFactory       : Created new connection: rabbitConnectionFactory#6ad5923a:0/SimpleConnection@64138b0c [delegate=amqp://guest@127.0.0.1:5672/, localPort= 44356]
DirectReceiver message:{createTime=2020-01-31 19:45:27, messageId=0c8961de-37c2-4c5d-a670-b07ccc48f8aa, messageData=test message, hello!}
2020-01-31 19:53:50.516  INFO 6386 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8022 (http) with context path ''
2020-01-31 19:53:50.518  INFO 6386 --- [           main] c.d.rabbitmq_consumer.DemoApplication    : Started DemoApplication in 2.476 seconds (JVM running for 3.115)

Fanout – 发布/订阅模式

扇型交换机,这个交换机没有路由键概念,就算你绑了路由键也是无视的. 这个交换机在接收到消息后,会直接转发到绑定到它上面的所有队列.

Fanout Producer

FanoutRabbitConfig.java

package com.dudu.rabbitmq_fanout_producer;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FanoutRabbitConfig {
    @Bean
    public Queue queueA() {
        return new Queue("fanout.A");
    }

    @Bean
    public Queue queueB() {
        return new Queue("fanout.B");
    }

    @Bean
    public Queue queueC() {
        return new Queue("fanout.C");
    }

    @Bean
    FanoutExchange fanoutExchange() {
        return new FanoutExchange("fanoutExchange");
    }

    @Bean
    Binding bindingExchangeA() {
        return BindingBuilder.bind(queueA()).to(fanoutExchange());
    }

    @Bean
    Binding bindingExchangeB() {
        return BindingBuilder.bind(queueB()).to(fanoutExchange());
    }

    @Bean
    Binding bindingExchangeC() {
        return BindingBuilder.bind(queueC()).to(fanoutExchange());
    }
}

SendMessageController.java

package com.dudu.rabbitmq_fanout_producer;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@RestController
public class SendMessageController {
    @Autowired
    RabbitTemplate rabbitTemplate;

    @GetMapping("/sendFanoutMessage")
    public String sendFanoutMessage() {
        String messageId = String.valueOf(UUID.randomUUID());
        String messageData = "message: testFanoutMessage ";
        String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        Map<String, Object> map = new HashMap<>();
        map.put("messageId", messageId);
        map.put("messageData", messageData);
        map.put("createTime", createTime);
        rabbitTemplate.convertAndSend("fanoutExchange", null, map);
        return "ok";
    }
}

application.properties

同direct producer application.properties

pom.xml

同direct producer pom.xml

Console Output

2020-01-31 21:58:10.405  INFO 13786 --- [           main] c.d.r.RabbitmqFanoutProducerApplication  : Starting RabbitmqFanoutProducerApplication on hugh-virtual-machine with PID 13786 (/home/hugh/IdeaProjects/rabbitmq_fanout_producer/target/classes started by hugh in /home/hugh/IdeaProjects/rabbitmq_fanout_producer)
2020-01-31 21:58:10.408  INFO 13786 --- [           main] c.d.r.RabbitmqFanoutProducerApplication  : No active profile set, falling back to default profiles: default
2020-01-31 21:58:11.433  INFO 13786 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8021 (http)
2020-01-31 21:58:11.442  INFO 13786 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2020-01-31 21:58:11.442  INFO 13786 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.30]
2020-01-31 21:58:11.500  INFO 13786 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2020-01-31 21:58:11.500  INFO 13786 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1015 ms
2020-01-31 21:58:11.703  INFO 13786 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2020-01-31 21:58:11.863  INFO 13786 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8021 (http) with context path ''
2020-01-31 21:58:11.865  INFO 13786 --- [           main] c.d.r.RabbitmqFanoutProducerApplication  : Started RabbitmqFanoutProducerApplication in 2.08 seconds (JVM running for 2.664)
2020-01-31 21:58:30.934  INFO 13786 --- [nio-8021-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-01-31 21:58:30.934  INFO 13786 --- [nio-8021-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2020-01-31 21:58:30.946  INFO 13786 --- [nio-8021-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 12 ms
2020-01-31 21:58:30.985  INFO 13786 --- [nio-8021-exec-2] o.s.a.r.c.CachingConnectionFactory       : Attempting to connect to: [127.0.0.1:5672]
2020-01-31 21:58:31.109  INFO 13786 --- [nio-8021-exec-2] o.s.a.r.c.CachingConnectionFactory       : Created new connection: rabbitConnectionFactory#7cf7aee:0/SimpleConnection@27d8690d [delegate=amqp://guest@127.0.0.1:5672/, localPort= 49870]

Fanout Consumer

FanoutReceiverA.java

package com.dudu.rabbitmq_fanout_consumer;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.util.Map;

@Component
@RabbitListener(queues = "fanout.A")
public class FanoutReceiverA {
    @RabbitHandler
    public void process(Map testMessage) {
        System.out.println("FanoutReceiverA message:" + testMessage.toString());
    }
}

FanoutReceiverB.java

package com.dudu.rabbitmq_fanout_consumer;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.util.Map;

@Component
@RabbitListener(queues = "fanout.B")
public class FanoutReceiverB {
    @RabbitHandler
    public void process(Map testMessage) {
        System.out.println("FanoutReceiverB message:" + testMessage.toString());
    }
}

FanoutReceiverC.java

package com.dudu.rabbitmq_fanout_consumer;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.util.Map;

@Component
@RabbitListener(queues = "fanout.C")
public class FanoutReceiverC {
    @RabbitHandler
    public void process(Map testMessage) {
        System.out.println("FanoutReceiverC message:" + testMessage.toString());
    }
}

application.properties

同Direct consumer application.properties

pom.xml

Console Output

2020-01-31 21:59:18.596  INFO 14054 --- [           main] c.d.r.DemoApplication                    : Starting DemoApplication on hugh-virtual-machine with PID 14054 (/home/hugh/IdeaProjects/rabbitmq_fanout_consumer/target/classes started by hugh in /home/hugh/IdeaProjects/rabbitmq_fanout_consumer)
2020-01-31 21:59:18.598  INFO 14054 --- [           main] c.d.r.DemoApplication                    : No active profile set, falling back to default profiles: default
2020-01-31 21:59:19.652  INFO 14054 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8022 (http)
2020-01-31 21:59:19.661  INFO 14054 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2020-01-31 21:59:19.662  INFO 14054 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.30]
2020-01-31 21:59:19.722  INFO 14054 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2020-01-31 21:59:19.722  INFO 14054 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1071 ms
2020-01-31 21:59:19.886  INFO 14054 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2020-01-31 21:59:20.204  INFO 14054 --- [           main] o.s.a.r.c.CachingConnectionFactory       : Attempting to connect to: [127.0.0.1:5672]
2020-01-31 21:59:20.276  INFO 14054 --- [           main] o.s.a.r.c.CachingConnectionFactory       : Created new connection: rabbitConnectionFactory#4fe01803:0/SimpleConnection@1f443fae [delegate=amqp://guest@127.0.0.1:5672/, localPort= 49926]
FanoutReceiverC message:{createTime=2020-01-31 21:58:30, messageId=8a2c6e80-0a90-4e51-8bac-97d44f5cb439, messageData=message: testFanoutMessage }
2020-01-31 21:59:20.392  INFO 14054 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8022 (http) with context path ''
2020-01-31 21:59:20.396  INFO 14054 --- [           main] c.d.r.DemoApplication                    : Started DemoApplication in 2.211 seconds (JVM running for 2.576)
FanoutReceiverA message:{createTime=2020-01-31 21:59:23, messageId=7d41d5de-303d-48db-a579-8c5851409b4d, messageData=message: testFanoutMessage }
FanoutReceiverC message:{createTime=2020-01-31 21:59:23, messageId=7d41d5de-303d-48db-a579-8c5851409b4d, messageData=message: testFanoutMessage }
FanoutReceiverB message:{createTime=2020-01-31 21:59:23, messageId=7d41d5de-303d-48db-a579-8c5851409b4d, messageData=message: testFanoutMessage }

Topic – 匹配订阅模式

主题交换机,这个交换机其实跟直连交换机流程差不多,但是它的特点就是在它的路由键和绑定键之间是有规则的.
简单地介绍下规则:

  • (星号) 用来表示一个单词 (必须出现的)
    (#) 用来表示任意数量(零个或多个)单词

通配的绑定键是跟队列进行绑定的,举个小例子
队列Q1 绑定键为 .TT. 队列Q2绑定键为 TT.#
如果一条消息携带的路由键为 A.TT.B,那么队列Q1将会收到;
如果一条消息携带的路由键为TT.AA.BB,那么队列Q2将会收到;

Publisher

application.properties

server.port= 8021
spring.application.name= rabbitmq-provider
spring.rabbitmq.host= 127.0.0.1
spring.rabbitmq.port= 5672
spring.rabbitmq.username= guest
spring.rabbitmq.password= guest

pom.xml

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

		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
	</dependencies>

TopicRabbitConfig

package com.dudu.rabbitmq_topic_publisher;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class TopicRabbitConfig {
    public final static String man = "topic.man";
    public final static String woman = "topic.woman";

    @Bean
    public Queue firstQueue() {
        return new Queue(TopicRabbitConfig.man);
    }

    @Bean
    public Queue secondQueue() {
        return new Queue(TopicRabbitConfig.woman);
    }

    @Bean
    TopicExchange topicExchange() {
        return new TopicExchange("topicExchange");
    }

    @Bean
    Binding bindingExchangeMessage() {
        return BindingBuilder.bind(firstQueue()).to(topicExchange()).with(man);
    }

    @Bean
    Binding bindingExchangeMessage2() {
        return BindingBuilder.bind(secondQueue()).to(topicExchange()).with("topic.#");
    }
}

SendTopicMessage

package com.dudu.rabbitmq_topic_publisher;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@RestController
public class SendTopicMessage {
    @Autowired
    RabbitTemplate rabbitTemplate;

    @GetMapping("/sendTopicMessage1")
    public String sendTopicMessage1() {
        String messageId = String.valueOf(UUID.randomUUID());
        String messageData = "message: MAN";
        String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        Map<String, Object> map = new HashMap<>();
        map.put("messageId", messageId);
        map.put("messageData", messageData);
        map.put("createTime", createTime);
        rabbitTemplate.convertAndSend("topicExchange", "topic.man", map);
        return "ok";
    }

    @GetMapping("sendTopicMessage2")
    public String sendTopicMessage2() {
        String messageId = String.valueOf(UUID.randomUUID());
        String messageData = "message: WOMAN";
        String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        Map<String, Object> map = new HashMap<>();
        map.put("messageId", messageId);
        map.put("messageData", messageData);
        map.put("createTime", createTime);
        rabbitTemplate.convertAndSend("topicExchange", "topic.woman", map);
        return "ok";
    }
}

Console Output

2020-02-01 10:04:41.269  INFO 63390 --- [           main] c.d.r.RabbitmqTopicPublisherApplication  : Starting RabbitmqTopicPublisherApplication on hugh-virtual-machine with PID 63390 (/home/hugh/IdeaProjects/rabbitmq_topic_publisher/target/classes started by hugh in /home/hugh/IdeaProjects/rabbitmq_topic_publisher)
2020-02-01 10:04:41.271  INFO 63390 --- [           main] c.d.r.RabbitmqTopicPublisherApplication  : No active profile set, falling back to default profiles: default
2020-02-01 10:04:42.415  INFO 63390 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8021 (http)
2020-02-01 10:04:42.423  INFO 63390 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2020-02-01 10:04:42.424  INFO 63390 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.30]
2020-02-01 10:04:42.480  INFO 63390 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2020-02-01 10:04:42.480  INFO 63390 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1168 ms
2020-02-01 10:04:42.693  INFO 63390 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2020-02-01 10:04:42.859  INFO 63390 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8021 (http) with context path ''
2020-02-01 10:04:42.862  INFO 63390 --- [           main] c.d.r.RabbitmqTopicPublisherApplication  : Started RabbitmqTopicPublisherApplication in 2.565 seconds (JVM running for 3.097)
2020-02-01 10:10:20.676  INFO 63390 --- [nio-8021-exec-3] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-02-01 10:10:20.677  INFO 63390 --- [nio-8021-exec-3] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2020-02-01 10:10:20.690  INFO 63390 --- [nio-8021-exec-3] o.s.web.servlet.DispatcherServlet        : Completed initialization in 13 ms
2020-02-01 10:10:20.760  INFO 63390 --- [nio-8021-exec-3] o.s.a.r.c.CachingConnectionFactory       : Attempting to connect to: [127.0.0.1:5672]
2020-02-01 10:10:20.923  INFO 63390 --- [nio-8021-exec-3] o.s.a.r.c.CachingConnectionFactory       : Created new connection: rabbitConnectionFactory#405325cf:0/SimpleConnection@5a890c78 [delegate=amqp://guest@127.0.0.1:5672/, localPort= 40732]

Subscriber

application.properties

server.port= 8022
spring.application.name= rabbitmq-consumer
spring.rabbitmq.host= 127.0.0.1
spring.rabbitmq.port= 5672
spring.rabbitmq.username= guest
spring.rabbitmq.password= guest

pom.xml

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

		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
	</dependencies>

TopicRabbitConfig.java

package com.dudu.rabbitmq_topic_subscriber;


import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class TopicRabbitConfig {
    public final static String man = "topic.man";
    public final static String woman = "topic.woman";

    @Bean
    public Queue firstQueue() {
        return new Queue(TopicRabbitConfig.man);
    }

    @Bean
    public Queue secondQueue() {
        return new Queue(TopicRabbitConfig.woman);
    }

    @Bean
    TopicExchange topicExchange() {
        return new TopicExchange("topicExchange");
    }

    @Bean
    Binding bindingExchangeMessage() {
        return BindingBuilder.bind(firstQueue()).to(topicExchange()).with(man);
    }

    @Bean
    Binding bindingExchangeMessage2() {
        return BindingBuilder.bind(secondQueue()).to(topicExchange()).with("topic.#");
    }
}

TopicManReceiver.java

package com.dudu.rabbitmq_topic_subscriber;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.util.Map;

@Component
@RabbitListener(queues = "topic.man")
public class TopicManReceiver {
    @RabbitHandler
    public void process(Map testMessage) {
        System.out.println("TopicManReceiver message:" + testMessage.toString());
    }
}

TopicTotalReceiver.java

package com.dudu.rabbitmq_topic_subscriber;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.util.Map;

@Component
@RabbitListener(queues = "topic.woman")
public class TopicTotalReceiver {
    @RabbitHandler
    public void process(Map testMessage) {
        System.out.println("TopicTotalReceiver message:" + testMessage.toString());
    }
}

Console Output

2020-02-01 10:09:41.645  INFO 63943 --- [           main] c.d.r.RabbitmqTopicSubscriberApplication : Starting RabbitmqTopicSubscriberApplication on hugh-virtual-machine with PID 63943 (/home/hugh/IdeaProjects/rabbitmq_topic_subscriber/target/classes started by hugh in /home/hugh/IdeaProjects/rabbitmq_topic_subscriber)
2020-02-01 10:09:41.653  INFO 63943 --- [           main] c.d.r.RabbitmqTopicSubscriberApplication : No active profile set, falling back to default profiles: default
2020-02-01 10:09:42.844  INFO 63943 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8022 (http)
2020-02-01 10:09:42.852  INFO 63943 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2020-02-01 10:09:42.853  INFO 63943 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.30]
2020-02-01 10:09:42.904  INFO 63943 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2020-02-01 10:09:42.904  INFO 63943 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1138 ms
2020-02-01 10:09:43.048  INFO 63943 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2020-02-01 10:09:43.278  INFO 63943 --- [           main] o.s.a.r.c.CachingConnectionFactory       : Attempting to connect to: [127.0.0.1:5672]
2020-02-01 10:09:43.360  INFO 63943 --- [           main] o.s.a.r.c.CachingConnectionFactory       : Created new connection: rabbitConnectionFactory#27b22f74:0/SimpleConnection@e4d2696 [delegate=amqp://guest@127.0.0.1:5672/, localPort= 40720]
2020-02-01 10:09:43.767  INFO 63943 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8022 (http) with context path ''
2020-02-01 10:09:43.769  INFO 63943 --- [           main] c.d.r.RabbitmqTopicSubscriberApplication : Started RabbitmqTopicSubscriberApplication in 2.487 seconds (JVM running for 2.886)
TopicManReceiver message:{createTime=2020-02-01 10:10:20, messageId=0570bfdd-15d6-44e8-a977-987531994e77, messageData=message: MAN}
TopicTotalReceiver message:{createTime=2020-02-01 10:10:20, messageId=0570bfdd-15d6-44e8-a977-987531994e77, messageData=message: MAN}
TopicTotalReceiver message:{createTime=2020-02-01 10:11:37, messageId=d604f4f0-1f86-499c-b6b0-d1aeba779536, messageData=message: WOMAN}

Confirm

Confirm Automatically

application.properties


server.port= 8021
spring.application.name= rabbitmq-consumer
spring.rabbitmq.host= 127.0.0.1
spring.rabbitmq.port= 5672
spring.rabbitmq.username= guest
spring.rabbitmq.password= guest
# Confirm message when sent to exchange
spring.rabbitmq.publisher-confirms= true
# Confirm message when send to queue
spring.rabbitmq.publisher-returns= true

消息推送到Server, 但是server里找不到交换机

RabbitConfig.java
package com.dudu.rabbitmq_confirm_provider;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitConfig {
    @Bean
    public RabbitTemplate createRabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate();
        rabbitTemplate.setConnectionFactory(connectionFactory);

        rabbitTemplate.setMandatory(true);

        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                System.out.println("ConfirmCallback:    " + "related data: " + correlationData);
                System.out.println("ConfirmCallback:    " + "Confirm: " + ack);
                System.out.println("ConfirmCallback:    " + "cause: " + cause);
            }
        });

        rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
            @Override
            public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
                System.out.println("ReturnCallback:     "+"消息:"+message);
                System.out.println("ReturnCallback:     "+"回应码:"+replyCode);
                System.out.println("ReturnCallback:     "+"回应信息:"+replyText);
                System.out.println("ReturnCallback:     "+"交换机:"+exchange);
                System.out.println("ReturnCallback:     "+"路由键:"+routingKey);
            }
        });
        return rabbitTemplate;
    }
}
SendMessageACK.java
package com.dudu.rabbitmq_confirm_provider;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@RestController
public class SendMessageACK {
    @Autowired
    RabbitTemplate rabbitTemplate;
    @GetMapping("/TestMessageACK")
    public String TestMessageACK() {
        String messageId = String.valueOf(UUID.randomUUID());
        String messageData = "message: non-existent-exchange test message ";
        String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        Map<String, Object> map = new HashMap<>();
        map.put("messageId", messageId);
        map.put("messageData", messageData);
        map.put("createTime", createTime);
        rabbitTemplate.convertAndSend("non-existent-exchange", "TestDirectRouting", map);
        return "ok";
    }
}
Console Output
2020-02-01 11:32:23.156  INFO 69050 --- [           main] c.d.r.RabbitmqConfirmProviderApplication : Starting RabbitmqConfirmProviderApplication on hugh-virtual-machine with PID 69050 (/home/hugh/IdeaProjects/rabbitmq_confirm_provider/target/classes started by hugh in /home/hugh/IdeaProjects/rabbitmq_confirm_provider)
2020-02-01 11:32:23.158  INFO 69050 --- [           main] c.d.r.RabbitmqConfirmProviderApplication : No active profile set, falling back to default profiles: default
2020-02-01 11:32:24.196  INFO 69050 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8021 (http)
2020-02-01 11:32:24.207  INFO 69050 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2020-02-01 11:32:24.207  INFO 69050 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.30]
2020-02-01 11:32:24.266  INFO 69050 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2020-02-01 11:32:24.267  INFO 69050 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1028 ms
2020-02-01 11:32:24.490  INFO 69050 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2020-02-01 11:32:24.650  INFO 69050 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8021 (http) with context path ''
2020-02-01 11:32:24.652  INFO 69050 --- [           main] c.d.r.RabbitmqConfirmProviderApplication : Started RabbitmqConfirmProviderApplication in 2.132 seconds (JVM running for 2.655)
2020-02-01 11:32:52.811  INFO 69050 --- [nio-8021-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-02-01 11:32:52.811  INFO 69050 --- [nio-8021-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2020-02-01 11:32:52.818  INFO 69050 --- [nio-8021-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 7 ms
2020-02-01 11:32:52.855  INFO 69050 --- [nio-8021-exec-1] o.s.a.r.c.CachingConnectionFactory       : Attempting to connect to: [127.0.0.1:5672]
2020-02-01 11:32:53.079  INFO 69050 --- [nio-8021-exec-1] o.s.a.r.c.CachingConnectionFactory       : Created new connection: rabbitConnectionFactory#6134ac4a:0/SimpleConnection@40a0df67 [delegate=amqp://guest@127.0.0.1:5672/, localPort= 41304]
2020-02-01 11:32:53.132 ERROR 69050 --- [ 127.0.0.1:5672] o.s.a.r.c.CachingConnectionFactory       : Channel shutdown: channel error; protocol method: #method<channel.close>(reply-code=404, 
reply]text=NOT_FOUND - no exchange 'non-existent-exchange' in vhost '/', class-id=60, method-id=40)
ConfirmCallback:    related data: null
ConfirmCallback:    Confirm: false
ConfirmCallback:    cause: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no exchange 'non-existent-exchange' in vhost '/', class-id=60, method-id=40)

消息推送到server,找到交换机了,但是没找到队列

RabbitConfig.java
    @Bean
    DirectExchange lonelyDirectExchange() {
        return new DirectExchange("lonelyDirectExchange");
    }
SendMessageACK.java
    @GetMapping("/TestMessageAck2")
    public String TestMessageAck2() {
        String messageId = String.valueOf(UUID.randomUUID());
        String messageData = "message: lonelyDirectExchange test message ";
        String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        Map<String, Object> map = new HashMap<>();
        map.put("messageId", messageId);
        map.put("messageData", messageData);
        map.put("createTime", createTime);
        rabbitTemplate.convertAndSend("lonelyDirectExchange", "TestDirectRouting", map);
        return "ok";
    }
Console Output
ReturnCallback:     消息:(Body:'{createTime=2020-02-01 11:38:51, messageId=fc3c8264-6691-4300-900b-cf7d18a8e3b3, messageData=message: lonelyDirectExchange test message }' MessageProperties [headers={}, contentType=application/x-java-serialized-object, contentLength=0, receivedDeliveryMode=PERSISTENT, priority=0, deliveryTag=0])
ReturnCallback:     回应码:312
ReturnCallback:     回应信息:NO_ROUTE
ReturnCallback:     交换机:lonelyDirectExchange
ReturnCallback:     路由键:TestDirectRouting
ConfirmCallback:    related data: null
ConfirmCallback:    Confirm: true
ConfirmCallback:    cause: null

消息推送成功

RabbitConfig.java
    @Bean
    public Queue lonelyQUeue() {
        return new Queue("lonelyQueue");
    }

    @Bean
    public DirectExchange lonelyDirectExchange() {
        return new DirectExchange("lonelyDirectExchange");
    }

    @Bean
    public Binding lonelyBinding() {
        return BindingBuilder.bind(lonelyQUeue()).to(lonelyDirectExchange()).with("TestDirectRouting");
    }
Console Output
2020-02-01 11:51:13.394  INFO 70395 --- [           main] c.d.r.RabbitmqConfirmProviderApplication : Starting RabbitmqConfirmProviderApplication on hugh-virtual-machine with PID 70395 (/home/hugh/IdeaProjects/rabbitmq_confirm_provider/target/classes started by hugh in /home/hugh/IdeaProjects/rabbitmq_confirm_provider)
2020-02-01 11:51:13.397  INFO 70395 --- [           main] c.d.r.RabbitmqConfirmProviderApplication : No active profile set, falling back to default profiles: default
2020-02-01 11:51:14.555  INFO 70395 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8021 (http)
2020-02-01 11:51:14.565  INFO 70395 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2020-02-01 11:51:14.565  INFO 70395 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.30]
2020-02-01 11:51:14.644  INFO 70395 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2020-02-01 11:51:14.644  INFO 70395 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1164 ms
2020-02-01 11:51:14.912  INFO 70395 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2020-02-01 11:51:15.100  INFO 70395 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8021 (http) with context path ''
2020-02-01 11:51:15.103  INFO 70395 --- [           main] c.d.r.RabbitmqConfirmProviderApplication : Started RabbitmqConfirmProviderApplication in 2.473 seconds (JVM running for 2.898)
2020-02-01 11:51:25.446  INFO 70395 --- [nio-8021-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-02-01 11:51:25.446  INFO 70395 --- [nio-8021-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2020-02-01 11:51:25.456  INFO 70395 --- [nio-8021-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 10 ms
2020-02-01 11:51:25.504  INFO 70395 --- [nio-8021-exec-1] o.s.a.r.c.CachingConnectionFactory       : Attempting to connect to: [127.0.0.1:5672]
2020-02-01 11:51:25.583  INFO 70395 --- [nio-8021-exec-1] o.s.a.r.c.CachingConnectionFactory       : Created new connection: rabbitConnectionFactory#3c1e23ff:0/SimpleConnection@6aa515c8 [delegate=amqp://guest@127.0.0.1:5672/, localPort= 41472]
ConfirmCallback:    related data: null
ConfirmCallback:    Confirm: true
ConfirmCallback:    cause: null

Confirm manually

不是很明白, 等有时间弄清楚

Reference

https://blog.csdn.net/qq_35387940/article/details/100514134

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!