RabbitMQ 概念
本文适有一定消息队列基础的,但没有接触过RabbitMQ的快速理解RabbitMQ.
如果从来没接触过RabbitMQ,那么让我们来设想一个基础的消息队列是怎样的呢?
//发送方,给一个队列名,就可以将消息发出
发送(QueueName,msg)
//接收方,给一个队列名就可以收到消息
while(true)
msg=接收(QueueName)
当然这是基础的点对点的队列,一个消息只被一个接收方消费一次。
还可以引入订阅机制,每个订阅者将收到一个订阅的完整内容。
//接收方
订阅(QueueName)
//订阅之后,系统会为这个订阅者保留一份消息副本,直到他消费。
//然后就可以象上面一样开始消息消息
while(true)
msg=接收(QueueName)
每个消息被所有订阅者都消费一次。
而RabbitMQ则比较复杂,多了大量概念,比如Exchange,Queue,Binding,
Connection,Channel,broker,virtual host...
初次接触会觉得很乱,我只是发个消息,为什么要了解这么多呢?
其实简单梳理一下,就会发现rabbitMQ并没有想象的那么复杂。
为了快速理解rabbitMQ的基本概念,你只需要关注Exchange,Queue,Binding。
其它概念都是具体编程时的细节,都可以放一放。
Exchange主要有三种类型direct,fanout,topic。也只要关注topic就可以了,
因为另外两类其实是topic的特例。
Queue,有一个唯一的名字,是一个标准的先进先出队列,而且每个队列中的消息只会被消费一次。
Binding则是描述exchange和queue之间的关系,之所以消息不直接发送到queue而是通过
exchange中转,并再由exchange和queue之间关系来决定最终消息投放到一个或多个队列,
甚至包括直接丢弃消息,仅仅是为了更方便的适合各种使用场景而已。
exchange和queue可以Bingding一个key,也就是首先连接了两者并且再定义了连接的类型(关系)。
而每个消息发送时也可以指定一个消息的routing_key。
比如我们可以让一个exchange和如下三个queue绑定
1.queue1,绑定key=#,所有exchange收到的消息都将转发给这个queue
2.queue2,绑定key=abc.def,只有routing_key=abc.def的消息才会转发到此queue。
3.queue3,绑定key=abc.*,转发所有routing_key为abc开头,且有两个字的消息。
可以想象,如果没有这样的绑定机制,要实现这三个队列,
就要求消息发送方根据情况多次发送同一个消息到对应的队列。
这正是RabbitMQ引入exchange来解决此类问题的方式。
关于绑定key通配符的进一步说明:
1.字是用.分隔的;a.b.c包含三个字,abc包含一个字
2.*代表任意一个字;a.*匹配a.b和a.c和a.d但不匹配a和a.b.c
3.#代表任意多个字;a.#匹配a和a.b和a.b.c。
Exchange direct类型是topic的一种特例,绑定关系只能是明确的不包含通配符的key,
而fanout类型则是忽略key,将所有消息转发给与他连接的queue。
一般情况下,发送时要指定一个exchange和消息的routing_key,
特例是,不指定exchange时,就用全局默认的direct类型exchange,
这样消息就只通过routing_key来决定投递到那个队列
(可以认为每个queue实际都是和全局direct exchage通过queue名字绑定的),
这实际就是我们最开始假想的标准消息队列。
通过增加更多其他exchange,在rabbitMQ内可以规划相互隔离或者相互交织的转发网络。
并且还可通过增加vhost,让用户感觉面对多个独立的rabbitMQ,来实现强隔离。
broker则指整个rabbitMQ,他可以包含多个vhost,客户端首先通过Connection连接到其中一个vhost,
比如IP+端口,为了复用连接,rabbitMQ再增加了Channel概念,在一个连接上可以同时并发多个Channel(类似会话),
channel仅仅是实现细节并不涉及具体概念,比如没有channel的话,rabbitMQ大可直接用连接与客户端交互
(这样可能要打开大量连接),类似mysql这种方式。
所以即便你从来没接触过rabbitMQ,现在也能大概知道如何用了。
伪码如下:
//发送
//打开连接
con=rabbitMQ.getConn(ip=,port=)
//打开channel
ch=con.getChannel()
//delivery_mode=2消息需要持久,不持久的话性能高,但是一旦崩溃会丢消息
ch.send(exchange=,routing_key=,msg=,delivery_mode=)
//关闭连接,实际可以只关闭channel而始终保持长连接
con.close()
//接收
con=rabbitMQ.getConn(ip=,port=)
ch=con.getChannel()
//接收时只需要指定queue,可选的是是否需要明确确认消息,
//不需要确认的话,消息一读,rabbitMQ就删除了,处理错误也不会再有机会了,
//当然这样性能更高
msg=ch.recive(queue=,no_ack=)
//处理消息
...
//确认处理完消息,确认后rabbitMQ就会删除对应消息
ch.ack(msg.id)
con.close()
好了,增加了消息是否需要持久,以及消息的确认,
每种语言有不同的API客户端,总体处理方式都是类似的。
上述代码没有包括建立exchange和queue,以及他们之间绑定的代码,
我们可以简单认为,这部分是通过其他方式另外定义的,对于收发客户端,
实际就只要提供上面这些参数就足够了。
这样看来RabbitMQ是不是很清晰简单?
当然rabbitMQ还包括一些其他的功能,比如RPC等,这类无非就是发送时指定更多参数罢了。
RabbitMQ 概念的更多相关文章
- rabbitMQ概念详细介绍
1. 历史 RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue )的开源实现.AMQP 的出现其实也是应了广大人民群众的需求,虽然在同步消息通讯的世界里有 ...
- RabbitMQ 概念与Java例子
RabbitMQ简介 目前RabbitMQ是AMQP 0-9-1(高级消息队列协议)的一个实现,使用Erlang语言编写,利用了Erlang的分布式特性. 概念介绍: Broker:简单来说就是消息队 ...
- RabbitMQ概念
RabbitMQ 即一个消息队列,_主要是用来实现应用程序的异步和解耦,同时也能起到消息缓冲,消息分发的作用._RabbitMQ使用的是AMQP协议,它是一种二进制协议.默认启动端口 5672. 在 ...
- Rabbitmq概念用法
MQ全称为Message Queue, 是一种分布式应用程序的的通信方法,它是消费-生产者模型的一个典型的代表,producer往消息队列中不断写入消息,而另一端consumer则可以读取或者订阅队列 ...
- 一、RabbitMQ 概念详解和应用
消息队列和同步请求的区别 无论RabbitMQ还是Kafka,本质上都是提供了基于message或事件驱动异步处理业务的能力,相比于http和rpc的直接调用,它有着不可替代的优势: 1. 解耦,解耦 ...
- rabbitmq概念简介
AMQP协议 AMQP: Advanced Message Queue,高级队列协议. 特征: 这是一个在进程间传递异步消息的网络协议,因此数据的发送方.接收方以及容器(MQ)都可以在不同的设备上. ...
- 【rabbitmq】rabbitmq概念解析--消息确认--示例程序
概述 本示例程序全部来自rabbitmq官方示例程序,rabbitmq-demo: 官方共有6个demo,针对不同的语言(如 C#,Java,Spring-AMQP等),都有不同的示例程序: 本示例程 ...
- RabbitMQ概念及环境搭建(四)RabbitMQ High Availability
#################################################### RabbitMQ High Availability #################### ...
- RabbitMQ概念及环境搭建(三)RabbitMQ cluster
测试环境:VMS00781 VMS00782 VMS00386 (centos5.8) 1.先在三台机器上分别安装RabbitMQ Server 2.读取其中一个节点的cookie,并复制到其他节点( ...
随机推荐
- IO流基础加强
字节流对象:InputStream,OutputStream 缓冲字节流对象:BufferedInputStream , BufferedOutputStream 用法和字符流对象一样,但也有区别, ...
- python 计算apache进程占用的内存大小以及占物理内存的比例
目的:计算所有apache进程占用的内存大小以及占物理内存的比例: 思路:利用系统中/proc/meminfo的现有数据进行统计 1.pidof列出服务对应进程的PID [root@yanglih ...
- 使用Node.js作为后台进行爬虫
看了一遍又一遍Node.js但是没过多久就又忘了,总想找点东西来练练手,就发现B站首页搜索框旁边的GIF图特别有意思,想着是不是可以写一个小Node.js项目把这些图全部扒下来,于是带着复习.预习与探 ...
- JavaScript OOP 创建对象的7种方式
我写JS代码,可以说一直都是面向过程的写法,除了一些用来封装数据的对象或者jQuery插件,可以说对原生对象了解的是少之又少.所以我拿着<JavaScript高级程序设计 第3版>恶补了一 ...
- linux 查看端口号命令
Linux下如果我们需要知道2809号端口的情况的话,我们可以这样,如下命令: $netstat -pan|grep 24800 tcp 0 0 0.0.0.0:24800 ...
- (C语言)char类型与int类型相加
#include <stdio.h> int main(void) { ; ; int c = a + b; a += b; printf("c=%d",c); //p ...
- 关于applicationx/www-form-urlencoded和multipart/form-data的描述
在Form元素的语法中,EncType表明提交数据的格式 用 Enctype 属性指定将数据回发到服务器时浏览器使用的编码类型. 下边是说明: application/x-www-form-urlen ...
- CodeChef CBAL
题面: https://www.codechef.com/problems/CBAL 题解: 可以发现,我们关心的仅仅是每个字符出现次数的奇偶性,而且字符集大小仅有 26, 所以我们状态压缩,记 a[ ...
- iOS 细节 问题
1.当一个空指针(nil pointer)调用了一个方法会发生什么? 安然无恙 —— 这是oc自带的消息机制,nil也能发送消息,而不会报错 2.为什么retainCount绝对不能用在发布的代码中? ...
- Coursera《machine learning》--(6)逻辑回归
六 逻辑回归(Logistic Regression:LR) 逻辑回归(Logistic Regression, LR)模型其实仅在线性回归的基础上,套用了一个逻辑函数,但也就是由于这个逻辑函数,使得 ...