rabbitmq的构架和原理(三)
前言
前面博文已经将安装配置和站点管理介绍了,现在开始正式学习rabbitmq的使用了;
rabbitMQ的构架
rabbitmq作为消息队列,一条消息从发布到订阅消费的完整流程为:
消息 --> 交换机exchange ---> 队列queue ---> 消费者
rabbitmq的核心就在交换机和队列
使用流程
发布者(推送消息的一端):
创建一个tcp长连接connection,连接rabbitmq的监听端口5672;
在TCP长连接下创建一个信道channel,信道可以理解为connection的一个分支;
通过信道向rabbitmq声明一个交换机exchange,设置交换机的类型,名称,是否持久化等属性;
通过信道向rabbitmq声明一个队列queue,设置队列的名称,是否持久化等参数;
通过信道向rabbitmq声明一个绑定binding,设置绑定的交换机名称,队列名称,绑定的路由键;
通过信道向rabbitmq推送一条消息,指定交换机和路由;
消费者(接收消息的一端):
从第一步到第四步和发布者做的事情是一模一样的,如果已经存在相应的exchange、queue等则跳过;
通过信道向rabbitmq声明一个订阅,订阅特定的queue,并且设置回调函数及是否确认等;
通过信道监听rabbitmq推送过来的消息;
深入理解
创建连接connection
rabbitmq实现的是AMQP通信协议,其所允许的最大AMQP连接数,本质上是TCP连接数;
采用TCP长连接,自带SSL认证机制,类似https,保证数据的传输安全;
其TCP连接的上限可以通过调整操作系统的限制来变更,详情linux修改TCP最大连接数
创建信道channel
信道channel可以理解成是connection下的分支,也就是说多个channel共享一个connection,为什么要这么做呢?
创建TCP连接是一个非常耗时的操作,如果一个应用需要多个connection的话,每次的创建和关闭会性能降低,而创建多个channel共享一个connection提高性能,节约系统资源;
多个channel是相互独立隔离的,这导致了一个问题就是,由于主机只能识别不同的TCP连接,但不能识别不同的信道发送过来的消息,因此rabbitmq为每个创建的信道分配了一个信道ID用来识别不同信道发送的消息;
每个信道都是为独立的进程或线程准备的,因此多线程或多进程共享信道是不被允许的;
在一个TCP下可创建的chnnel的数量理论上是没有上限的,只取决于系统资源,但可以通过配置channel_max参数设置上限;
声明交换机exchange
作用:交换机使用来管理分发消息的,一边接受发布者提交的消息,根据消息提供的参数选择相应的处理办法,交换机是不会存储消息的,只有转发或丢弃功能;
如果消息携带的路由键没有对应的路由队列,交换机会将消息丢弃;
声明交换机时的重要属性:
name:名称,必须唯一;
type:类型,共有四种,默认direct;
Durability:是否持久化,默认否;
Auto delete:是否自动删除;
Internal:是否是内部交换机,默认否;
Arguments:设置额外的参数;
交换机的类型
直连交换机direct
顾名思义直连交换机根据消息携带的路由键将该消息投递到绑定的队列;
如果有多个队列使用相同的路由键和直连交换机绑定,那么直连交换机会将消息同时转发到多个队列;
rabbitmq本身存在默认交换机,默认交换机的本质就是名称为空的直连交换机,当任何一个新的队列被声明的时候,rabbitmq会使用这个队列的名字作为路由键自动绑定默认交换机;
通过rabbitmqctl list_exchanges命令查看所有的交换机,可以看到有一个名称为空的direct;
扇形交换机funout
作用:扇形交换机会将消息推送到绑定的所有的队列中,不会理会路由键是什么;
在声明funout和队列绑定的时候,也有一个路由键参数,但是写什么都无所谓,funout会将其忽略的;
主题交换机topic
- 作用:主题交换机使用比较复杂的路由键匹配规则实现一路或多路路由;
路由键规则:
使用.分割的词语列表,也可以是单个词语,长度不能超过255个字节;
*号用来匹配一个单词,这个单词不能为空,#号用来匹配0个或多个单词;
user.* 用来匹配所有绑定了以user开头并且使用了两个单词的路由键;
user.# 用来匹配所有绑定了以user开头并且使用了一个以上单词的所有路由键;
头交换机headers
通过判断消息中携带的额外的属性来分发消息给对应的队列,性质和直连交换机很相似;
其区别在于使用消息的属性替换路由键作为路由的规则;
注意
每个交换机的名字是唯一的,如果重复声明交换机并且声明的参数完全一样,那么mq会忽略该声明;
如果声明交换机已经存在,但修改了它的属性,比如类型或持久化等,那么会报错;所以修改的方法是先删除原来的交换机再创建一个新的交换机;
队列queue
queue用来缓存消息,并向消费者推送消息;
声明队列的名称最多255个字节,可以是任意字符串;
如果声明时名字为空,mq会随机生成一个名字;
声明队列不可以用amq.开头,否则报错, amq.是rabbitmq内部使用的默认队列;
如果多个消费者订阅同一个队列的消息,那么队列会用轮询的方式推送消息,这种方式可以实现负载均衡;
注意:
每个队列的名字是唯一的,如果重复声明交换机并且声明的参数完全一样,那么mq会忽略该声明;
如果声明的该队列已经存在,但修改了它的属性,比如类型或持久化等,那么会报错;所以修改的方法是先删除原来的队列再创建一个新的队列;
消息订阅
消费者可以向队列订阅消息,每个消费者都会被分配一个标志符;
订阅时可以设置消费回执,告诉mq什么时候可以将消息删除了,默认是自动删除的;
消费者也可以向mq发送 拒绝消息 ,这时消息会被放回队列等待投递到其他的消费者;
消费者订阅的时候可以设置预取计数,当存在多个消费者共同订阅一个队列的时候,由于是轮询机制,但每个消费者的消费能力可能是不一样的,这可能造成有的消费者闲的要死,有的忙的要死,设置预取数量,在没有收到回执确认前,该队列推送的消息是有限的,可以提高整体的吞吐量;
消息,交换机,队列的持久化
消息持久化是在消息投递前定义的,设置了持久化后,消息会被保存在磁盘,当被消费后会从磁盘中删除,但是也不能保证100%持久化成功,因为消息是先放到内存中的,如果此时主机崩溃,还是会有一部分来不及写入磁盘;
交换机持久化是在声明该交换机的时候设置的,当主机崩溃或重启后,mq一重新上线会自动重新声明一个和原来完全一样的交换机;
队列持久化是在队列被声明的时候设置的,mq重新上线会自动重新声明一个和原来完全一样的queue,但是队列里的消息会全部丢失;
参考
rabbitmq的构架和原理(三)的更多相关文章
- rabbitmq之核心构架和原理总结(四)
前言 前面博文已经将安装配置和站点管理介绍了,现在开始正式学习rabbitmq的使用了: rabbitMQ的构架 rabbitmq作为消息队列,一条消息从发布到订阅消费的完整流程为: 消息 --> ...
- 跟vczh看实例学编译原理——三:Tinymoe与无歧义语法分析
文章中引用的代码均来自https://github.com/vczh/tinymoe. 看了前面的三篇文章,大家应该基本对Tinymoe的代码有一个初步的感觉了.在正确分析"print ...
- word2vec原理(三) 基于Negative Sampling的模型
word2vec原理(一) CBOW与Skip-Gram模型基础 word2vec原理(二) 基于Hierarchical Softmax的模型 word2vec原理(三) 基于Negative Sa ...
- RabbitMQ基本概念和原理
RabbitMQ基本概念和原理 1.AMQP,即Advanced Message Queuing Protocol,高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计. 2.Rabb ...
- 并发之AQS原理(三) 如何保证并发
并发之AQS原理(三) 如何保证并发 1. 如何保证并发 AbstractQueuedSynchronizer 维护了一个state(代表了共享资源)和一个FIFO线程等待队列(多线程竞争资源被阻塞时 ...
- RabbitMQ的构架
初识rabbitMQ RabbitMQ 是一个由 Erlang 语言开发的 AMQP 的开源实现. AMQP :Advanced Message Queue,高级消息队列协议.它是应用层协议的一个开放 ...
- Vue项目搭建及原理三
我每次写博客都要先在本地写一遍草稿,所以之前有些发布顺序可能会有一丢丢凌乱 哈哈哈,以后绝对改正,那下面我们就说一下创建及项目目录结构吧 三.创建项目 1.初始化Webpack p.p1 { marg ...
- 【c#】RabbitMQ学习文档(三)Publish/Subscribe(发布/订阅)
(本教程是使用Net客户端,也就是针对微软技术平台的) 在前一个教程中,我们创建了一个工作队列.工作队列背后的假设是每个任务会被交付给一个[工人].在这一部分我们将做一些完全不同的事情--我们将向多个 ...
- socket通信原理三次握手和四次握手详解
对TCP/IP.UDP.Socket编程这些词你不会很陌生吧?随着网络技术的发展,这些词充斥着我们的耳朵.那么我想问: 1. 什么是TCP/IP.UDP?2. Sock ...
随机推荐
- 如何给网站添加SSL证书(免费)
上篇讲了如何将网站部署到服务器上,这篇就讲如何给网站添加SSL证书. 1.先到腾讯云ssl证书认证那里申请一个证书 2.DNS认证 3.下载解压nginx里面的文件 4. 在服务器上/www目录下创建 ...
- 喵哈哈村的魔法考试 Round #1 (Div.2) 题解&源码(A.水+暴力,B.dp+栈)
A.喵哈哈村的魔法石 发布时间: 2017年2月21日 20:05 最后更新: 2017年2月21日 20:06 时间限制: 1000ms 内存限制: 128M 描述 传说喵哈哈村有三种神 ...
- CodeForces798-B. Mike and strings-string中的find()函数
好久好久好久之前的一个题,今天翻cf,发现这个题没过,补一下. B. Mike and strings time limit per test 2 seconds memory limit per t ...
- POJ1163-The Triangle-动态规划
The Triangle Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 50122 Accepted: 30285 De ...
- Zabbix如何实现批量监控端口状态
引言 ------------------------------------------------------------------------------------------------- ...
- gulp + es6 + babel+ angular 搭建环境并实现简单的路由
1.ECMAscript 6的语法糖面临的唯一问题就是浏览器兼容的问题,使得很多程序员望而怯步. 2.babel的作用就是将es6的语法编译成es5被浏览器所识别.这样就可以任性的使用es6了. 3. ...
- 【CC2530入门教程-增强版】基础技能综合实训案例(基础版)-上位机源码
[CC2530入门教程-增强版]基础技能综合实训案例(基础版)-上位机源码 广东职业技术学院 欧浩源 一.需求分析 按照指定参数打开串口,与测控终端建立数据传输通道,并根据应用要求实现程序逻辑,具体 ...
- Docker+Jenkins持续集成环境(2)使用docker+jenkins构建nodejs前端项目
前文使用Docker搭建Jenkins+Docker持续集成环境我们已经搭建了基于docker+jenkins的持续集成环境,并构建了基于maven的项目.这一节,我们继续扩展功能,增加对Nodejs ...
- UE4 小笔记
1,设置postprocess材质时使用Add or Update Blendable 用Make PostprocessSetting会报警告,因为C++代码中没有设置为BlueprintReadW ...
- Vue2反向代理
前一段时间写了一个vue2的小项目,用的是vue-cli脚手架搭建的项目,项目里需要跨域,但又不能使用jsonp,上网查了一下,发现有一个之前没接触过的词语--反向代理. 什么是"反向代 ...