rabbitmq
PHP实现消息队列MQ
1、MQ的应用场景
优点:
a)主要解决异步消息
b)应用解耦
c)流量消峰等问题
d)日志处理(kafka)
缺点:
a)系统可用性降低:你想啊,本来其他系统只要运行好好的,那你的系统就是正常的。现在你非要加个消息队列进去,那消息队列挂了,你的系统不是呵呵了。因此,系统可用性降低
b)系统复杂性增加:要多考虑很多方面的问题,比如一致性问题、如何保证消息不被重复消费,如何保证保证消息可靠传输。因此,需要考虑的东西更多,系统复杂性增大。
1、为什么会造成重复消费?
因为网络传输等等故障,确认信息没有传送到消息队列,导致消息队列不知道自己已经消费过该消息了,再次将该消息分发给其他的消费者。
2、解决重复消费的方案:
(1)比如,你拿到这个消息做数据库的insert操作。那就容易了,给这个消息做一个唯一主键,那么就算出现重复消费的情况,就会导致主键冲突,避免数据库出现脏数据。
(2)再比如,你拿到这个消息做redis的set的操作,那就容易了,不用解决,因为你无论set几次结果都是一样的,set操作本来就算幂等操作。
(3)如果上面两种情况还不行,上大招。准备一个第三方介质,来做消费记录。以redis为例,给消息分配一个全局id,只要消费过该消息,将以K-V形式写入redis。那消费者开始消费前,先去redis中查询有没消费记录即可。
2、消息模型
a)P2P(Point to Point)点对点模式(也就是一个任务只能被一个消费者消费)
1、包含三个角色:消息队列(Queue),发送者(Sender),接受者(Receiver)
PHP实现:
安装rabbitMQ扩展:
在你的项目中添加一个 composer.json文件:
{
“require”: {
“php-amqplib/php-amqplib”: “2.6.1”
}
}
2、简单模式(一对一)
php
@File : sample-send.php
@Author: Liugp
@Date : 2019/7/22
@Desc : 生产者
require_once DIR . ‘/vendor/autoload.php’;
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;
// 建立AMQP连接
$connection = new AMQPStreamConnection(’localhost’, 5672, ‘guest’, ‘guest’);
$channel = $connection->channel();
// 定义队列名称
$channel->queue_declare(‘hello’, false, false, false, false);
// 定义要发送的信息
…