上节我们简单了解了springboot2.x整合consul的入门教程,在最后的时候的时候遗留了整合RabbitMQ的过程,接下来我们来看详细的过程
什么是RabbitMQ?
RabbitMQ是消息队列的一种,其目的也是为了程序的异步和解耦,同样也是为了消息的缓存和分发的作用.
RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件,用在分布式系统来存储转发消息,其服务器端用Erlang语言编写,支持多种客户端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP 等,支持 AJAX.在易用性、扩展性、高可用性等方面表现不俗.
RabbitMQ相关组件介绍
通常我们在说到消息队列时,都会谈到生产者. 队列 . 消费者,而RabbitMQ在这之上多了一层抽象,在生产者和队列之间加入了交换机(Exchange)的概念,使得生产者和队列没有直接联系,而是将之前的消息转发的方式变为先是转发到交换机(Exchange),在由交换机(Exchange)转发到消息队列中.如图:
我们来看看上图每一部分都代表着什么?
- 上图左侧P代表生产者.
- 中间的部分为RabbitMQ,其中包含了交换机和队列.
- 右侧C代表消息的消费者.
在上述的组件中,其中最为重要的是虚拟机,交换机,队列和绑定,分别来看:
- 虚拟主机:一个虚拟主机包括一般持有一组交换机.队列和绑定,为什么需要多个虚拟主机呢?很简单, RabbitMQ 当中,用户只能在虚拟主机的粒度进行权限控制。 因此,如果需要禁止A组访问B组的交换机/队列/绑定,必须为A和B分别创建一个虚拟主机。每一个 RabbitMQ 服务器都有一个默认的虚拟主机''/''.
Exchange
交换机(Exchange)只用来消息的转发,不做消息的存储,如果此时没有队列(Queue)绑定到交换机,会直接丢掉生产者(Producer)发送的消息,这里涉及到一个路由键的概念,消息交换到交换机的时候,交换机会找到对应的队列(Queue)中,就是通过路由键来决定.
再者交换机(Exchange)的本质只是用作消息的转发到绑定的队列中,常见的交换机有四种模式,分别是:Direct,topic,Headers,Fanout.
- Direct:该类型的消息推送规则是先匹配,然后在把消息推送到由路由键(routingKey)指定的队列中,如图所示:
- Topic:按规则转发消息
-
Headers:需要设置headers的属性(attribute)类型的交换机即可.
-
Fanout:以广播的方式发布消息
上述为简单介绍了交换机(Exchange)的四种模式,图是从别人那里接的,接下来我们来看重点springboot整合RabbitMQ的过程.
整合RabbitMQ过程
在我们之前搭建的服务(consul-producer)生产者中进行改造,首先是在pom文件中进行RabbitMQ依赖的添加,代码如下:
org.springframework.boot
spring-boot-starter-amqp
接着我们来看RabbitMQ来如何配置队列以及交换机和绑定的过程,代码如下:
package com.consul.mq;
import org.springframework.context.annotation.Configuration;
/**
* @author cb
*/
@Configuration
public class TopicRabbitConfig {
}
接着来看RabbitMQ的配置文件,代码如下:
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
#配置虚拟主机
spring.rabbitmq.virtual-host=/
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
上述配置中我们看到了username和password,其中guest为RabbitMQ安装的初始用户名和初始密码,想改的话自己可以去改.
具体的创建队列和交换机以及绑定,我们只需要在RabbitMQ的管理界面手动创建即可,可能大家在看别的文章时,都是通过代码的方式来创建队列等,来看如何创建的过程,前期是大家安装了RabbitMQ,首先来启动RabbitMQ,cmd到RabbitMQ安装路径的sbin目录下,执行:
rabbitmq-plugins enable rabbitmq_management
如图:
该命令主要是来下载RabbitMQ的一些相关插件,此时我们的服务起来了,接着访问http://localhost:15672,来到该页面,输入用户名和密码(均为guest)
我们来看如何创建Exchange和queue,如图:
上图为添加Exchange的过程,我们来看添加队列的过程,如图:
接着我们来看队列和交换机如何绑定,如图:
点击我们创建的交换机(Exchange),来到上图的界面,输入队列名和以及路由键(这里根据交换机的类型来输入,有的交换机不需要路由键),所有的都准备妥当,我们需要创建消息的生产者和消费者,来看代码:
package com.consul.send;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* @author cb
*/
@Component
public class MessageProducer {
@Autowired
private RabbitTemplate rabbitTemplate;
public void send1(){
Date date = new Date();
for (int i=0;i<5;i++){
String msg = "在时间为:"+ date+"生产了一个消息";
System.out.println("producer:"+msg);
rabbitTemplate.convertAndSend("topic.exchange","topic.routingKey",msg);
}
}
//fanout类型的
public void fanoutSend(){
String content = "类型为Fanout的交换机:"+System.currentTimeMillis();
System.out.println("FanoutProducer:"+content);
rabbitTemplate.convertAndSend("fanout.exchange","",content);
}
在来看消费者代码:
package com.consul.consumer;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* @author cb
*/
@Component
public class MessageConsumer {
@RabbitListener(queues = "topic.queueA")
@RabbitHandler
public void receive(String message){
System.out.println("Consumer:"+message);
}
@RabbitListener(queues = "fanout.queue")
@RabbitHandler
public void fanoutReceive(String content){
System.out.println("Consumer:"+content);
}
我们通过@RabbitListener来监听我们创建的队列,如代码中的topic.queueA,来看运行结果:
这是我们的后台消费者端的打印输出,我们再来看,RabbitMQ管理台queue中的消息总数,如图:
消息被我们消费完了,这就是RabbitMQ的简单使用过程