RabbitMQ

RabbitMQ 是一个由 Erlang 语言开发的 AMQP 的开源实现。
特点包括:
1. 可靠性( Reliability
RabbitMQ 使用一些机制来保证可靠性,如持久化、传输确认、发布确认。
2. 灵活的路由(Flexible Routing)
在消息进入队列之前,通过 Exchange 来路由消息的。对于典型的路由功能, RabbitMQ
已经提供了一些内置的 Exchange 来实现。针对更复杂的路由功能,可以将多个
Exchange 绑定在一起,也通过插件机制实现自己的 Exchange
3. 消息集群( Clustering
多个 RabbitMQ 服务器可以组成一个集群,形成一个逻辑 Broker
4. 高可用( Highly Available Queues
队列可以在集群中的机器上进行镜像,使得在部分节点出问题的情况下队列仍然可用。
5. 多种协议( Multi-protocol
RabbitMQ 支持多种消息队列协议,比如 STOMP MQTT 等等。
6. 多语言客户端( Many Clients
RabbitMQ 几乎支持所有常用语言,比如 Java .NET Ruby 等等。
7. 管理界面( Management UI
RabbitMQ 提供了一个易用的用户界面,使得用户可以监控和管理消息 Broker 的许多方
面。
8. 跟踪机制(Tracing)
如果消息异常, RabbitMQ 提供了消息跟踪机制,使用者可以找出发生了什么。
9. 插件机制( Plugin System
RabbitMQ 提供了许多插件,来从多方面进行扩展,也可以编写自己的插件。
1.3 架构图与主要概念
1.3.1 架构图

 1.3.2主要概念

RabbitMQ Server : 也叫 broker server ,它是一种传输服务。 他的角色就是维护一条
Producer Consumer 的路线,保证数据能够按照指定的方式进行传输。
Producer : 消息生产者,如图 A B C ,数据的发送方。消息生产者连接 RabbitMQ
务器然后将消息投递到 Exchange
Consumer :消息消费者,如图 1 2 3 ,数据的接收方。消息消费者订阅队列,
RabbitMQ Queue 中的消息发送到消息消费者。
Exchange :生产者将消息发送到 Exchange (交换器),由 Exchange 将消息路由到一个
或多个 Queue 中(或者丢弃)。 Exchange 并不存储消息。 RabbitMQ 中的 Exchange
direct fanout topic headers 四种类型,每种类型对应不同的路由规则。
Queue :(队列)是 RabbitMQ 的内部对象,用于存储消息。消息消费者就是通过订阅
队列来获取消息的, RabbitMQ 中的消息都只能存储在 Queue 中,生产者生产消息并最终
投递到 Queue 中,消费者可以从 Queue 中获取消息并消费。多个消费者可以订阅同一个
Queue ,这时 Queue 中的消息会被平均分摊给多个消费者进行处理,而不是每个消费者
都收到所有的消息并处理
RoutingKey :生产者在将消息发送给 Exchange 的时候,一般会指定一个 routing key
来指定这个消息的路由规则,而这个 routing key 需要与 Exchange Type binding key
合使用才能最终生效。在 Exchange Type binding key 固定的情况下(在正常使用时一
般这些内容都是固定配置好的),我们的生产者就可以在发送消息给 Exchange 时,通过
指定 routing key 来决定消息流向哪里。 RabbitMQ routing key 设定的长度限制为 255
bytes
Connection : (连接): Producer Consumer 都是通过 TCP 连接到 RabbitMQ Server
的。以后我们可以看到,程序的起始处就是建立这个 TCP 连接。
Channels : (信道):它建立在上述的 TCP 连接中。数据流动都是在 Channel 中进行
的。也就是说,一般情况是程序起始建立 TCP 连接,第二步就是建立这个 Channel
VirtualHost :权限控制的基本单位,一个 VirtualHost 里面有若干 Exchange
MessageQueue ,以及指定被哪些 user 使用
2.1 RabbitMQ 安装与启动
2.1.1 windows 环境下的安装
1 )下载并安装 Eralng
(2)下载并安装 rabbitmq
(3)安装管理界面(插件)
进入 rabbitMQ 安装目录的 sbin 目录,输入命令
rabbitmq‐plugins enable rabbitmq_management
(4)重新启动服务
5 )打开浏览器,地址栏输入 http://127.0.0.1:15672 , 即可看到管理界面的登陆页

输入用户名和密码,都为guest 进入主界面:

 

 

最上侧的导航依此是:概览、连接、信道、交换器、队列、用户管理
2.1.2 docker 环境下的安装
1 )下载镜像:
docker pull rabbitmq:management
(2)创建容器, rabbitmq 需要有映射以下端口 : 5671 5672 4369 15671 15672
25672
15672 (if management plugin is enabled)
15671 management 监听端口
5672, 5671 (AMQP 0-9-1 without and with TLS)
4369 (epmd) epmd 代表 Erlang 端口映射守护进程
25672 (Erlang distribution)
docker run ‐di ‐‐name=tensquare_rabbitmq ‐p 5671:5617 ‐p 5672:5672 ‐p
4369:4369 ‐p 15671:15671 ‐p 15672:15672 ‐p 25672:25672 rabbitmq:management
浏览器访问 http://192.168.184.134:15672/#/
2.2 直接模式( Direct
2.2.1 什么是 Direct 模式
我们需要将消息发给唯一一个节点时使用这种模式,这是最简单的一种形式。

 任何发送到Direct Exchange的消息都会被转发到RouteKey中指定的Queue

1. 一般情况可以使用 rabbitMQ 自带的 Exchange ”"( Exchange 的名字为空字符串,下
文称其为 default Exchange)
2. 这种模式下不需要将 Exchange 进行任何绑定 (binding) 操作
3. 消息传递时需要一个 “RouteKey” ,可以简单的理解为要发送到的队列名字。
4. 如果 vhost 中不存在 RouteKey 中指定的队列名,则该消息会被抛弃。
2.2.2 创建队列
做下面的例子前,我们先建立一个叫csdn 的队列。

 Durability:是否做持久化 Durable(持久) transient(临时)

Auto delete : 是否自动删除
2.2.3 代码实现 - 消息生产者
1 )创建工程 rabbitmq_demo ,引入 amqp 起步依赖 , pom.xml 如下:
<?xml version="1.0"?>
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring‐boot‐starter‐parent</artifactId>
    <version>2.0.1.RELEASE</version>
    <relativePath />
</parent>
<properties>
    <project.build.sourceEncoding>UTF‐ 8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF‐ 8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
</properties>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring‐boot‐starter‐amqp</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring‐boot‐starter‐test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring‐boot‐maven‐plugin</artifactId>
        </plugin>
    </plugins>
</build>
(2)编写配置文件 application.yml
spring:
 rabbitmq:
     host: 192.168.184.134
(3)编写启动类
@SpringBootApplication 
public class Application { 
    public static void main(String[] args) {
     SpringApplication.run(Application.class); 
    } 
}
(4)编写测试类
@RunWith(SpringRunner.class)
@SpringBootTest(classes=Application.class)
public class MqTest { 

    @Autowired private RabbitTemplate rabbitTemplate; 

    @Test public void testSend(){ 

    rabbitTemplate.convertAndSend("csdn","我要红包"); 

    }

}
运行测试方法
2.2.4 代码实现 - 消息消费者
1 )编写消息消费者类
@Component 
@RabbitListener(queues="csdn" ) 
public class Customer1 { 
    @RabbitHandler 
    public void showMessage(String message){ 

    System.out.println("csdn接收到消息:"+message); 

    } 
}
(2)运行启动类,可以在控制台看到刚才发送的消息
2.2.5 测试
开启多个消费者工程,测试运行消息生产者工程,会发现只有一个消费者工程可以接收
到消息。
如何在 IDEA 中多次启动同一个程序呢?
1 )选择 IDEA 右上角的类名称按钮

 

(2)选择 Edit Configurations
(3)在弹出窗口中取消单例模式 ,点击 OK

 (4)每次运行前修改application.yml,指定不同的端口

server: 
    port: 9202
运行后在控制台可以看到多个窗口
2.3 分列模式( Fanout
2.3.1 什么是分列( Fanout )模式

 当我们需要将消息一次发给多个队列时,需要使用这种模式。如下图:

 

任何发送到 Fanout Exchange 的消息都会被转发到与该 Exchange 绑定 (Binding) 的所有
Queue 上。
1. 可以理解为路由表的模式
2. 这种模式不需要 RouteKey
3. 这种模式需要提前将 Exchange Queue 进行绑定,一个 Exchange 可以绑定多个
Queue ,一个 Queue 可以同多个 Exchange 进行绑定。
4. 如果接受到消息的 Exchange 没有与任何 Queue 绑定,则消息会被抛弃。
2.3.2 交换器绑定队列
1 )在 queue 中添加队列q1   和q2
(2)新建交换器exchange1
(3)将 q1  q2 两个队列绑定到交换器 exchange1

点击exchange1进入交换器管理界面 

 点击Bindings添加绑定 q1q2

绑定后效果如下:

 

2.3.3 代码实现-消息生产者 

 

@Test 
public void testSendFanout(){ 
    rabbitTemplate.convertAndSend("exchange1","", "分列模式走起"); 

}
2.3.4 代码实现 - 消息消费者
创建消息监听类,用于监听 q1 的消息
@Component 
@RabbitListener(queues="q1" ) 
public class Customer2 { 
    @RabbitHandler 
    public void showMessage(String message){ 
        System.out.println("q1接收到消息:"+message); 
    } 

}
创建消息监听类,用于监听 q2 的消息
@Component 
@RabbitListener(queues="q2" ) 
public class Customer3 { 
    @RabbitHandler 
    public void showMessage(String message){ 
        System.out.println("kudingyu接收到消息:"+message); 
    } 
}
2.3.5 测试
启动消费者工程,发送消息测试

 

 2.4 主题模式(Topic

2.4.1 什么是主题模式

任何发送到 Topic Exchange 的消息都会被转发到所有关心 RouteKey 中指定话题的 Queue

 如上图所示

此类交换器使得来自不同的源头的消息可以到达一个对列,其实说的更明白一点就是模

糊匹配的意思,例如:上图中红色对列的 routekey usa.#,#代表匹配任意字符,
但是 要想消息能到达此对列,usa.必须匹配,后面的 #可以随意. 图中 usa.news 、 usa.weather,都能找到红色队列,符号 # 匹配一个或多个词, 符号 * 匹配不多不少一个词。因此 usa.# 能够匹配到 usa.news.XXX ,但是 usa.* 只会匹配到 usa.XXX
注:
交换器说到底是一个名称与队列绑定的列表。 当消息发布到交换器时,实际上是由你所
连接的信道,将消息路由键同交换器上绑定的列表进行比较,最后路由消息。
任何发送到 Topic Exchange 的消息都会被转发到所有关心 RouteKey 中指定话题的
Queue
1. 这种模式较为复杂,简单来说,就是每个队列都有其关心的主题,所有的消息都带有一
标题 ”(RouteKey) Exchange 会将消息转发到所有关注主题能与 RouteKey 模糊匹配的
队列。
2. 这种模式需要 RouteKey ,也许要提前绑定 Exchange Queue
3. 在进行绑定时,要提供一个该队列关心的主题,如 “#.log.#” 表示该队列关心所有涉及
log 的消息 ( 一个 RouteKey ”MQ.log.error” 的消息会被转发到该队列 )
4.“#” 表示 0 个或若干个关键字, 表示一个关键字。如 “log. 能与 “log.warn” 匹配,无法
“log.warn.timeout” 匹配;但是 “log.#” 能与上述两者匹配。
5. 同样,如果 Exchange 没有发现能够与 RouteKey 匹配的 Queue ,则会抛弃此消息
2.4.2 创建队列与绑定
1 )新建一个交换器 ,类型选择 topic
(2)点击新建的交换器 topictest

 

添加匹配规则,添加后列表如下:

 

2.4.3 代码实现 

编写测试类方法:
@Test 
public void testSendTopic1(){ 

rabbitTemplate.convertAndSend("topictest","goods.aaa","主题模式"); 


}
输出结果: q1 接收到消息:主题模式
@Test 
public void testSendTopic2(){ 

    rabbitTemplate.convertAndSend("topictest","article.content.log","主题模 式");

}
输出结果: q2 接收到消息:主题模式 
@Test
public void testSendTopic3(){ 

    rabbitTemplate.convertAndSend("topictest","goods.log","主题模式"); 

}
输出结果:
q1 接收到消息:主题模式
q2 接收到消息:主题模式
q3 接收到消息:主题模式
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值