安装与初次使用
安装
Mac 没什么好说的.
$brew update
$brew install rabbitmq
然后安装在这里, /usr/local/sbin/rabbitmq-server 如果命令没有就 .bash_profile 加一下对应的PATH
首次运行
$rabbitmq-server
$rabbitmqctl status
队列
AMQP 是什么呢,不知道就别TM往下读了,反正也不会 简单来说 AMQP 是一个搭载在TCP上的协议,这个协议定义了信道的规范然后允许在一个AMQP连接中建立多个信道, 然后我们开始说说消息路由,三个组成部分分别是 交换器, 队列和绑定。 生产者把消息放在exchange中选择对应的queue当然这就取决于咱们的消息究竟绑定了什么
因此我们通过AMQP basic.consume 来订阅消息,这种方式叫做持续订阅,你会源源不断的接受属于你这条队列上的消息, 如果你想获取一条可以使用 basic.get,如果你想用while true + basic.get 来替代 consume,那么你一定是脑子瓦特了,不要忽略取消订阅的成本。
当我们的队列拥有多个消费者的时候,消息通过round-robin 哇偶,把轮询说的这么牛逼真的好么,每个消息只会发给一个订阅的消费者,这个场景真的解决了不少问题,比如说有没有那个二货还在想用mysql自己维护消息队列的时候采用什么样级别的锁来保证消息只被读到过一次
消息打到seed_bin 队列
Rabbit MQ 把消息Message_A
Farmer Bob 接受了Message_A 发出了确认
rabbitmq就把 seed_bin 中 Message A 干掉了
这也就是说在消费者 在接受到消息之后发送了basic.ack 当然也可能在定于到达队列的事后就已经将auto_ack = true 了,这只是消费者和队列之间的通信,生产者对此事并不知情。这就好比说Mary 想跟同时跟很多人表白,但是表白的信息肯定只能给一个人看见。那么除了basic.get 接受了表白,当然在发现了mary是个绿茶婊之后你也可能选择拒绝她,于是乎你可以置之不理,但是显然,如果大家都置之不理的话,这个表白的链接要重新进行建立,mary可能挺累的,所以说拒绝别人也是讲究艺术的,在rabbit2.0以后你就可以使用basic.reject这种优雅的方式拒绝接受这样的表白,同时如果你觉得妹子写封信挺不容易的,这信可以寄给别人,那么你记得在参数里加一个 requeue=true,如果你觉得,这个绿茶婊别糟蹋别的小伙了,那你就设置成false这样这条表白就不会发给别人了。同时这些被遗弃的表白信就都在一个叫dead letter的死心队列中,当然这个队列也是可以查看的,妹子可以通过积累经验看下自己为啥被拒绝。
总结一下队列是什么?
首先是一个存放消息的住所
对负载均衡来说,队列是绝佳的方案
队列是消息最后的终点
交换器和绑定
好,继续我们绿茶婊的故事,一起认识一下AMQP是怎么把mary的信寄到所有他想表白的消费者手中呢。首先表白信要通过交换器到达具体的队列,mary在信中写上朝阳区,然后交换器就会通过你的路由键将这封信投递到朝阳区的队列中,可能是朝阳区的小伙子比较好上钩这样子。如果mary失手填成了水帘洞区,没有对应的匹配,消息将会进入黑洞。
那么交换器一共分为四种,direct fanout topic headers 每一种都有对应不同的算法,我好像在说废话。。。闲话不多说,大概区别一下好了。
headers:
匹配的事AMQP消息的头部信息而不是路由键, 其余跟direct可以说是一样一样的
direct:
如刚才所说 direct 跟headers唯一不同之处就是他通过路由键来进行匹配。
$channel ->basic_publish($msg, '', 'queue-name');
已经建立的信道之后,你便可以通过这个方法发送你想要的内容给指定的队列,其中第一个参数是消息内容, 第二个参数是交换器, 最后一个参数就是路由键了,你想发给‘大鸭梨’ 只要队列有大鸭梨这个队列那就不会发给大苹果,放心, 好用。
当然了默认的交换器不能满足的时候你也可以通过 exchange.declare 来声明自己的交换器.
fanout:
fan是什么。。。风扇把,fanout是不是就是把表白的信随着风飘散这样子。。。哈哈感觉其实也差不多,fanout就是广播类型的交换器,当你发送一条给fanout交换器,他便会广播给所有人,跟邻村的三姑六婆一样的碎嘴,只不过记性好一点,每个人能保证只说一次。
当同一件事发生触发了交换器而你的领导希望在触发的同时,你还需要添加一些别的时间,通过fanout你只需要把新建立的queue附加在这个对应的交换器即可,不然你可能还要修改当前的逻辑代码,直接发给某个队列中。
topic:
当我先绑定了topic约会,我就可以收到所有关于约会这个topic的消息啦
$channel->queue_bind(
'msg-inbox',
'logs-exchange',
'date.msg_inbox'
)
这是一个发送约会消息的方法:
$channel->basic_publish($msg, 'msgs-exchange', 'date.msg-inbox');
topic交换可以支持更多有趣的通信场景,比如说吧你想把消息的类别分的更具体一点,约会是约会,工作是工作那么你就应该要把不同的queue绑定到对应的交换器上,并且指定你的topic, 上述的两步看起来就是直接通过最后一个参数来进行交换,跟direct没有什么区别,但是我们可以通过缺省的
$channel ->queue_bind('msg-inbox', 'msgs-exchange', *.dates)
把所有'.dates'结尾的消息都分配给这个queue 同事有几个需要记得就是'*'代表特定位置的任意文本,'#'表示所有匹配规则.
那么到这里我们把基本上可能会用到的概念回顾一下:
AMQP的重要组成, 分别是队列 交换器 绑定。
通过不同的绑定规则把队列绑定在交换器上
交换器类型 headers, direct, fanout, topic