声明:文章写于2016-11-10,项目中RabbitMQ的使用方式在后面可能会发生变化。
消息队列(MessageQueue)的好处:
- 简化业务流程
- 异步处理消息
- 减少组件耦合
- 消减数据峰值
消息队列的应用场景:
- 场景1:
支付成功以后,给用户发送优惠券or红包; -
场景2:
用户注册成功后发送通知邮件or短信; -
场景3:
活动里面的站内信发送;
. . . . . .
总结起来就是,把单个业务简洁化,通过消息系统把不相关的业务连接起来,实现更复杂的业务链,降低整个系统的复杂度。
安装
安装方法自行google,如果要在生产环境中安装请先联系运维,涉及到安全问题。
项目中使用
//发布消息
use CI123\Shop\Tool\RabbitMq\Publisher;
Publisher::publish('routing_key', $message);
//监听消息
use Api\Tool\RabbitMq\Subscriber;
Subscriber::subscribe('routing_key', function ($msgObj) {
$message = $msgObj->body;
Subscriber::ack($msgObj);
});
以上是对RabbitMQ极其简陋的介绍,下面是重点:
一、我们项目中怎么设置RabbitMQ的:
1. 持久化
真正的持久保存消息,需要设置三个地方:
1.1 将交换机设置成durable;
1.2 将队列设置成durable;
1.3 将消息的delivery_mode设置成2;
PS:
缺少任何一个设置,都无法真正持久化;
持久化会消耗额外的性能;
2. 自动删除
2.1 消息在队列里存在时间是5分钟;
2.2 队列本身存在时间是30分钟;
2.3 过期的消息会被移出到“死信队列”;
2.4 死信队列里的消息存在7天;
2.5 死信队列本身存在10天;
3. 消费者应答机制(ack/nack机制)
3.1 如果消息已经被正确消费了,你可以通过ack方法告诉rabbitmq,rabbitmq会删除这条消息;
3.2 反之,你可以调用nack告诉RabbitMQ消费失败,rabbitmq会立马将消息移到“死信队列”;
3.3 或者什么都不做,等待消息过期后被移动到“死信队列”。
4. 生产者确认机制(Confirm机制)
4.1 发布消息后,发送者可以通过异步的回调知道消息是否发送成功;
PS:目前项目中基本没有使用。
二、初步理解RabbitMQ
1. 四个比较重要的概念
- 虚拟主机(vhost):每个vhost都有单独一套交换器、队列、绑定规则
- 交换器(exchange):将消息发送到队列
常见相关名词:
+ 名称(exchange):交换器名字,不能重复
+ 类型(type):fanout/direct/topic/headers
+ 持久化(durable):服务重启后是否要恢复
+ 自动删除(auto-delete):没有队列使用交换器时自动删除 - 队列(queue):存取消息
常见相关名词:
+ 名称(queue):队列名字,不能重复
+ 持久化(durable):服务重启后是否要恢复
+ 自动删除(auto-delete):没有消费者时自动删除
+ 声明(arguments): 消息存在时间(x-message-ttl)、队列存在时间(x-expires) - 绑定(binding):将队列和交换机绑定,以通过routing_key来收发消息;
2. 四种Exchange
- fanout :广播
- direct:routing_key全部匹配
- topic:可以理解为在direct的基础上给routing_key增加了正则匹配,当然肯定不是正则;
- headers:消息里包含headers,如果消息的headers和队列能匹配上就将消息投递到该headers,可以指定是完全匹配(all)还是只需要匹配单个(one);
3. 其他概念和结论
- 消息的获取有主动拉取、被动接收,发布/订阅模式是被动接收;
- 交换器、队列的属性一旦声明就不可更改,但是绑定是可以解绑的(unbind);
- 当一个 message 被路由到多个 queue 中时,在某个 queue 中的某个 message 的“死亡”不会对相同 message 在其他 queue 中的生存状况;
- 同时设置了队列生存时间T1和消息生存时间T2后,消息在队列中的存在时间是T1/T2之中的最小值;
- 如果没有设置死信队列,即便你设置了durable,消息到期后也会被丢弃;
4.目前的使用状况
- 按照普通的消息队列来使用:佣金、理财、保险;
- 改造为延时队列:微信模板消息,通过延时队列来重发上次发送失败的消息;
- 可以改造为任务队列使用:待定;