SpringBoot集成RabbitMQ

匿名 (未验证) 提交于 2019-12-02 23:45:01

下载带有管理界面的RabbitMQ Docker镜像

docker pull rabbitmq:3.7.7-management

然后创建并运行RabbitMQ容器

docker run -d --name rabbitmq3.7.7 -p 5672:5672 -p 15672:15672 -v `pwd`/data:/var/lib/rabbitmq --hostname myRabbit -e RABBITMQ_DEFAULT_VHOST=my_vhost  -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin rabbitmq:3.7.7-management   docker run -d --hostname rabbitmqhost --name rabbitmq3.6 --restart always -p 5672:5672  -p 15672:15672 -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin rabbitmq:3.6.15-management

-d:后台运行
--hostname:设置容器的主机名
--name:容器命名
--restart always:开机启动
-p:端口号映射,前面是宿主机端口,后面是容器端口
-v:挂载宿主机目录到容器目录
-e:设置容器环境变量

游览器访问:http://服务器ip地址:15672
输入启动容器是设置的用户名密码登录就进去管理页面啦

交换机的主要功能是接收消息并转发到绑定的队列,交换机自身不存储消息,当启动ack模式后,交换机找不到指定的队列会返回错误。交换机类型有Direct、topic、 Headers、Fanout四种类型

Direct Exchange 是 RabbitMQ 默认的交换机模式,也是最简单的模式,根据key全文匹配去寻找队列。发送消息是设置一个routing_key,当routing_key匹配时才将消息传送到绑定的队列中。

Topic Exchange跟Direct Exchange类似,在匹配上增加了模式概念,从以点分开的routing_key形式中,可用使用2中统配符:*表示一个单词,#表示0个或者多个单词

Headers Exchange是一个自定义匹配规则的类型,在交换器与队列绑定时,会制定一组键值对规则,发送消息时也会制定一组规则,当这些键值对有一对或者多对匹配时,消息会传送到对应的队列中。

Fanout Exchange用的是消息广播模式,设置路由建无效,它会把消息传送给交换机下的所有队列。

创建一个主工程:spring-boot-rabbitmq,添加如下内容:

<parent>     <groupId>org.springframework.boot</groupId>     <artifactId>spring-boot-starter-parent</artifactId>     <!--<version>2.1.5.RELEASE</version>-->     <version>1.5.20.RELEASE</version> </parent>  <properties>     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>     <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>     <java.version>1.8</java.version>     <spring-boot.version>1.5.20.RELEASE</spring-boot.version> </properties>  <dependencyManagement>     <dependencies>         <dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-dependencies</artifactId>             <version>${spring-boot.version}</version>             <type>pom</type>             <scope>import</scope>         </dependency>     </dependencies> </dependencyManagement>

在spring-boot-rabbitmq主工程中创建一个RabbitMQ配置的Maven module:rabbitmq-config
添加如下依赖:

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

创建一个配置类:RabbitConfig.java,添加如下内容

@Configuration public class RabbitConfig {      //创建一个hello-queue消息队列     @Bean     public Queue helloQueue() {         return new Queue("hello-queue");     } }

在spring-boot-rabbitmq主工程中创建一个消息发送方的SpringBoot module:rabbitmq-sender
在pom文件中添加如下依赖:

<dependency>     <groupId>org.springframework.boot</groupId>     <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency>     <groupId>com.alyshen</groupId>     <artifactId>rabbitmq-config</artifactId>     <version>${project.version}</version> </dependency> <dependency>     <groupId>org.springframework.boot</groupId>     <artifactId>spring-boot-starter-amqp</artifactId> </dependency>

在resource目录下创建配置文件:application.properties,添加如下内容:

############### 服务配置 ############# server.port=9000 spring.application.name=rabbitmq-sender  ############### RabbitMQ配置 ############## spring.rabbitmq.host=192.168.86.101 spring.rabbitmq.port=5672 spring.rabbitmq.username=admin spring.rabbitmq.password=admin

创建工程启动类:RabbitmqSenderApplication.java,添加如下内容:

@SpringBootApplication public class RabbitmqSenderApplication {      public static void main(String[] args) {         SpringApplication.run(RabbitmqSenderApplication.class,args);     } }

创建一个消息生产者:HelloQueueSender.java

@Component public class HelloQueueSender {      @Autowired     private AmqpTemplate amqpTemplate;      public void send(String msg) {         String context = msg + ",sender date:" + new Date();         System.out.println("Sender to hello-queue: " + context);         this.amqpTemplate.convertAndSend("hello-queue", context);//使用hello-queue队列     } }

创建一个HelloSenderController供浏览器发送消息,添加如下内容:

@RestController public class HelloSenderController {      @Autowired     private HelloQueueSender helloQueueSender;      @RequestMapping(value = "/senderMessage")     public String senderMessage(@PathParam(value = "msg") String msg){         helloQueueSender.send(msg);         return "sender ok...";     } }

运行项目rabbitmq-sender,访问:
http://localhost:9000/senderMessage?msg=消息内容
这时消息内容保存到rabbitmq队列中待消息消费方获取

创建一个消息接收方的SpringBoot工程:rabbitmq-receiver
在pom文件中添加如下依赖:

<dependency>     <groupId>org.springframework.boot</groupId>     <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency>     <groupId>com.alyshen</groupId>     <artifactId>rabbitmq-config</artifactId>     <version>${project.version}</version> </dependency> <dependency>     <groupId>org.springframework.boot</groupId>     <artifactId>spring-boot-starter-amqp</artifactId> </dependency>

在resource目录下创建配置文件:application.properties,添加如下内容:

############### 服务配置 ############# server.port=9100 spring.application.name=rabbitmq-receiver  ############### RabbitMQ配置 ############## spring.rabbitmq.host=192.168.86.101 spring.rabbitmq.port=5672 spring.rabbitmq.username=admin spring.rabbitmq.password=admin

创建工程启动类:RabbitmqReceiverApplication.java
添加如下内容:

@SpringBootApplication public class RabbitmqReceiverApplication {      public static void main(String[] args) {         SpringApplication.run(RabbitmqReceiverApplication.class,args);     } }

在rabbitmq-receiver的pom文件中加入rabbitmq-config工程依赖

创建一个消息处理者:HelloQueueReceiver.java

@Component @RabbitListener(queues = "hello-queue") public class HelloQueueReceiver {      @RabbitHandler     public void process(String hello){         System.out.println("Receiver:" + hello);     } }

启动工程rabbitmq-receiver,输出内容:
Receiver:消息内容,……

即获取到消息内容

将rabbitmq-sender中的HelloSenderController内容修改成如下所示:

@RestController public class HelloSenderController {      @Autowired     private HelloQueueSender helloQueueSender;      @RequestMapping(value = "/senderMessage")     public String senderMessage(@PathParam(value = "msg") String msg) {         for (int i = 1; i <= 20; i++) {             helloQueueSender.send(i + "," + msg);         }         return "sender ok...";     } }

把rabbitmq-receiver中的HelloQueueReceiver.java复制一份,分别改成如下:
HelloQueueReceiver.java

@Component @RabbitListener(queues = "hello-queue") public class HelloQueueReceiver {      @RabbitHandler     public void process(String msg) {         System.out.println("Receiver 1:" + msg);     } }

HelloQueueReceiver2.java

@Component @RabbitListener(queues = "hello-queue") public class HelloQueueReceiver2 {      @RabbitHandler     public void process(String msg){         System.out.println("Receiver 2:" + msg);     } }

将rabbitmq-sender和rabbitmq-receiver运行起来
访问http://localhost:9000/senderMessage?msg=消息内容

rabbitmq-sender控制台输出:
Sender to hello-queue: 1,消息内容,……
Sender to hello-queue: 2,消息内容,……
Sender to hello-queue: 3,消息内容,……
Sender to hello-queue: 4,消息内容,……
Sender to hello-queue: 5,消息内容,……
Sender to hello-queue: 6,消息内容,……
Sender to hello-queue: 7,消息内容,……
Sender to hello-queue: 8,消息内容,……
Sender to hello-queue: 9,消息内容,……
Sender to hello-queue: 10,消息内容,……
Sender to hello-queue: 11,消息内容,……
Sender to hello-queue: 12,消息内容,……
Sender to hello-queue: 13,消息内容,……
Sender to hello-queue: 14,消息内容,……
Sender to hello-queue: 15,消息内容,……
Sender to hello-queue: 16,消息内容,……
Sender to hello-queue: 17,消息内容,……
Sender to hello-queue: 18,消息内容,……
Sender to hello-queue: 19,消息内容,……
Sender to hello-queue: 20,消息内容,……

rabbitmq-receiver控制台输出:

Receiver 1:1,消息内容,……
Receiver 2:2,消息内容,……
Receiver 1:3,消息内容,……
Receiver 2:4,消息内容,……
Receiver 1:5,消息内容,……
Receiver 2:6,消息内容,……
Receiver 1:7,消息内容,……
Receiver 2:8,消息内容,……
Receiver 1:9,消息内容,……
Receiver 2:10,消息内容,……
Receiver 1:11,消息内容,……
Receiver 2:12,消息内容,……
Receiver 1:13,消息内容,……
Receiver 2:14,消息内容,……
Receiver 1:15,消息内容,……
Receiver 2:16,消息内容,……
Receiver 1:17,消息内容,……
Receiver 2:18,消息内容,……
Receiver 1:19,消息内容,……
Receiver 2:20,消息内容,……

可以看出消息消费方是轮流有序的获取消息的

将rabbitmq-sender中的HelloQueueSender复制一份创建HelloQueueSender2,就类名不一样,其他都一样
改造一下rabbitmq-sender工程中的HelloSenderController,改成入下:

@RestController public class HelloSenderController {      @Autowired     private HelloQueueSender helloQueueSender;     @Autowired     private HelloQueueSender2 helloQueueSender2;      @RequestMapping(value = "/senderMessage")     public String senderMessage(@PathParam(value = "msg") String msg) {         for (int i = 1; i <= 20; i++) {             helloQueueSender.send("sender1 " + i + "." + msg);             helloQueueSender2.send("sender2 " + i + "." + msg);         }         return "sender ok...";     } }

运行rabbitmq-sender
访问http://localhost:9000/senderMessage?msg=消息内容

rabbitmq-sender控制台输出
Sender to hello-queue: sender1 1.消息内容,……
Sender to hello-queue: sender2 1.消息内容,……
Sender to hello-queue: sender1 2.消息内容,……
Sender to hello-queue: sender2 2.消息内容,……
Sender to hello-queue: sender1 3.消息内容,……
Sender to hello-queue: sender2 3.消息内容,……
Sender to hello-queue: sender1 4.消息内容,……
Sender to hello-queue: sender2 4.消息内容,……
Sender to hello-queue: sender1 5.消息内容,……
Sender to hello-queue: sender2 5.消息内容,……
Sender to hello-queue: sender1 6.消息内容,……
Sender to hello-queue: sender2 6.消息内容,……
Sender to hello-queue: sender1 7.消息内容,……
Sender to hello-queue: sender2 7.消息内容,……
Sender to hello-queue: sender1 8.消息内容,……
Sender to hello-queue: sender2 8.消息内容,……
Sender to hello-queue: sender1 9.消息内容,……
Sender to hello-queue: sender2 9.消息内容,……
Sender to hello-queue: sender1 10.消息内容,……
Sender to hello-queue: sender2 10.消息内容,……
Sender to hello-queue: sender1 11.消息内容,……
Sender to hello-queue: sender2 11.消息内容,……
Sender to hello-queue: sender1 12.消息内容,……
Sender to hello-queue: sender2 12.消息内容,……
Sender to hello-queue: sender1 13.消息内容,……
……

rabbitmq-receiver的控制台输出:
Receiver 1:sender1 1.消息内容,……
Receiver 2:sender2 1.消息内容,……
Receiver 1:sender1 2.消息内容,……
Receiver 2:sender2 2.消息内容,……
Receiver 1:sender1 3.消息内容,……
Receiver 2:sender2 3.消息内容,……
Receiver 1:sender1 4.消息内容,……
Receiver 2:sender2 4.消息内容,……
Receiver 1:sender1 5.消息内容,……
Receiver 2:sender2 5.消息内容,……
Receiver 1:sender1 6.消息内容,……
Receiver 2:sender2 6.消息内容,……
Receiver 1:sender1 7.消息内容,……
Receiver 2:sender2 7.消息内容,……
Receiver 1:sender1 8.消息内容,……
Receiver 2:sender2 8.消息内容,……
Receiver 1:sender1 9.消息内容,……
Receiver 2:sender2 9.消息内容,……
Receiver 2:sender2 10.消息内容,……
Receiver 1:sender1 10.消息内容,……
Receiver 1:sender1 11.消息内容,……
Receiver 2:sender2 11.消息内容,……
Receiver 1:sender1 12.消息内容,……
Receiver 2:sender2 12.消息内容,……
Receiver 2:sender1 13.消息内容,……
Receiver 1:sender2 13.消息内容,……

可以看出在多对多情况下消息依然是有序取出的

在spring-boot-rabbitmq主工程中创建一个model module:rabbitmq-model
添加一个model:User
内容如下:

public class User implements Serializable {      public static final Long serialVersionUID = 1L;      private String username;     private String passwd;     private int age;      @Override     public String toString() {         return "User{" +                 "username='" + username + '\'' +                 ", passwd='" + passwd + '\'' +                 ", age=" + age +                 '}';     }      public String getUsername() {         return username;     }      public void setUsername(String username) {         this.username = username;     }      public String getPasswd() {         return passwd;     }      public void setPasswd(String passwd) {         this.passwd = passwd;     }      public int getAge() {         return age;     }      public void setAge(int age) {         this.age = age;     } }

分别在rabbitmq-sender和rabbitmq-receiver工程中加入rabbitmq-model依赖

<dependency>     <groupId>com.alyshen</groupId>     <artifactId>rabbitmq-model</artifactId>     <version>${project.version}</version> </dependency>

在rabbitmq-config工程中的配置类RabbitmqConfig.java加入方法:

 //创建一个user-queue消息队列 @Bean public Queue userQueue() {     return new Queue("user-queue"); }

在rabbitmq-sender工程中参加一个生产方:UserSender.java,内容如下:

@Component public class UserSender {     @Autowired     private AmqpTemplate amqpTemplate;      public void senderUser(User user) {         System.out.println("Sender to user-queue: " + user);         amqpTemplate.convertAndSend("user-queue",user);     } }

在添加一个Controller:UserSenderController.java,内容如下:

@RestController public class UserSenderController {      @Autowired     UserSender userSender;      @RequestMapping(value = "/sendUser")     public String senduser() {         User user = new User();         user.setUsername("zhangshan");         user.setPasswd("zzzpwd");         user.setAge(20);         userSender.senderUser(user);         return "sender user ok ...";     } }

运行rabbitmq-sender工程,浏览器访问:http://localhost:9000/sendUser,控制台输出:
Sender to user-queue: User{username='zhangshan', passwd='zzzpwd', age=20}

一个username为zhangshan的User就加入了user-queue队列中

现在rabbitmq-receiver工程中创建一个User消息接收方:UserReceiver.java,内容如下:

@Component public class UserReceiver {      //    @RabbitHandler     @RabbitListener(queues = "user-queue")     public void process(User user) {         System.out.println("Receiver user:" + user);     } }

运行rabbitmq-receiver工程,控制台输出:
Receiver user:User{username='zhangshan', passwd='zzzpwd', age=20}

User信息接收成功

在rabbitmq-config工程中创建配置类TopicRabbitConfig.java,内容如下:

@Configuration public class TopicRabbitConfig {      final static String message = "topic.message";     final static String messages = "topic.messages";      @Bean     public Queue queueMessage() {         return new Queue(TopicRabbitConfig.message);     }      @Bean     public Queue queueMessages() {         return new Queue(TopicRabbitConfig.messages);     }      /**      * @Title exchange      * @Description 创建个Topic交换机      */     @Bean     TopicExchange exchange() {         return new TopicExchange("topicExchange");     }     /**      * @Title bindingExchangeMessage      * @Description 交换机和路由建绑定      */     @Bean     Binding bindingExchangeMessage(Queue queueMessage, TopicExchange exchange) {         return BindingBuilder.bind(queueMessage).to(exchange).with("topic.message");     }      @Bean     Binding bindingExchangeMessages(Queue queueMessages, TopicExchange exchange) {         return BindingBuilder.bind(queueMessages).to(exchange).with("topic.#");     } }

在rabbitmq-sender工程中添加topic消息发送方:TopicSender.java,添加如下内容:

@Component public class TopicSender {      @Autowired     private AmqpTemplate rabbitTemplate;      public void sender() {         String context = "消息1...";         System.out.println("Sender : " + context);         this.rabbitTemplate.convertAndSend("topicExchange", "topic.xxx", context);     }      public void sender2() {         String context = "消息2...";         System.out.println("Sender : " + context);         this.rabbitTemplate.convertAndSend("topicExchange", "topic.message", context);     }      public void sender3() {         String context = "消息3...";         System.out.println("Sender : " + context);         this.rabbitTemplate.convertAndSend("topicExchange", "topic.messages", context);     } }

再创建一个TopicSenderController,添加如下内容:

@RestController public class TopicSenderController {      @Autowired     private TopicSender topicSender;      @RequestMapping(value = "/topic")     public String topic() {         topicSender.sender();         return "sender ok...";     }      @RequestMapping(value = "/topic2")     public String topic2() {         topicSender.sender2();         return "sender ok...";     }      @RequestMapping(value = "/topic3")     public String topic3() {         topicSender.sender3();         return "sender ok...";     } }

在rabbitmq-receiver工程中创建topic消息接收端:TopicReceiver1.java,添加如下内容:

@Component public class TopicReceiver1 {     //    @RabbitHandler     @RabbitListener(queues = "topic.message")     public void process(String message) {         System.out.println("Topic Receiver 1:" + message);     } }

在创建一个topic消息接收端:TopicReceiver2.java,添加如下内容:

@Component public class TopicReceiver2 {  //    @RabbitHandler     @RabbitListener(queues = "topic.messages")     public void process(String message) {         System.out.println("Topic Receiver 2:" + message);     }  }

运行rabbitmq-sender和rabbitmq-receiver
浏览器访问:http://localhost:9000/topic
发现只有Receiver 2接收到消息1,说明topic.xxx匹配的是topic.#这个规则

浏览器访问:http://localhost:9000/topic2
发现Receiver 1和Receiver 2都接收到了消息2,说明topic.message匹配的是topic.message和topic.#这两个规则

浏览器访问:http://localhost:9000/topic3
发现只有Receiver 2都接收到了消息3,说明topic.messages匹配的是topic.#这个规则

在rabbitmq-config工程中创建配置类FanoutRabbitConfig.java,添加如下内容:

@Configuration public class FanoutRabbitConfig {      //创建队列a     @Bean     public Queue AMessage() {         return new Queue("fanout.A");     }      @Bean     public Queue BMessage() {         return new Queue("fanout.B");     }      @Bean     public Queue CMessage() {         return new Queue("fanout.C");     }  //    创建Fanout 交换机     @Bean     FanoutExchange fanoutExchange() {         return new FanoutExchange("fanoutExchange");     }      //队列绑定交换机     @Bean     Binding bindingExchangeA(Queue AMessage, FanoutExchange fanoutExchange) {         return BindingBuilder.bind(AMessage).to(fanoutExchange);     }      @Bean     Binding bindingExchangeB(Queue BMessage, FanoutExchange fanoutExchange) {         return BindingBuilder.bind(BMessage).to(fanoutExchange);     }      @Bean     Binding bindingExchangeC(Queue CMessage, FanoutExchange fanoutExchange) {         return BindingBuilder.bind(CMessage).to(fanoutExchange);     }  }

在rabbitmq-sender工程中添加fanout消息发送方:FanoutSender.java,添加如下内容:

@Component public class FanoutSender {     @Autowired     private AmqpTemplate rabbitTemplate;      public void sender() {         String context = "fanout 消息内容...";         System.out.println("Sender : " + context);         this.rabbitTemplate.convertAndSend("fanoutExchange", "", context);     } }

再创建一个FanoutSenderController,添加如下内容:

@RestController public class FanoutSenderController {     @Autowired     private FanoutSender fanoutSender;      @RequestMapping(value = "/fanout")     public String topic() {         fanoutSender.sender();         return "sender ok...";     } }

在rabbitmq-receiver工程中创建fanout消息接收端:FanoutReceiver.java,添加如下内容:

@Component public class FanoutReceiver {     //    @RabbitHandler     @RabbitListener(queues = "fanout.A")     public void process(String message) {         System.out.println("fanout Receiver A:" + message);     }      @RabbitListener(queues = "fanout.B")     public void process2(String message) {         System.out.println("fanout Receiver B:" + message);     }      @RabbitListener(queues = "fanout.C")     public void process3(String message) {         System.out.println("fanout Receiver C:" + message);     } }

运行rabbitmq-sender和rabbitmq-receiver
浏览器访问:http://localhost:9000/fanout

在rabbitmq-receiver工程的控制台下输出:
fanout Receiver B:fanout 消息内容...
fanout Receiver C:fanout 消息内容...
fanout Receiver A:fanout 消息内容...

说明绑定到fanout交换机上的队列都接收到了消息

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