https://www.imooc.com/video/15163php
冗余:延迟处理、保障完成 解耦:出入解耦 流量消峰:redis缓存 异步通讯:异步场景 方便扩展:解耦的结果 排序保证:顺序处理
-- 订单系统【生产方】 --
接收订单,核心代码:mysql
//把订单信息保存到订单表中 $db = DB::getIntance(); $res = $db->insert("order_queue", $insert_data);
-- 配送系统【消费方】 --
定时发货,核心代码:git
//1. 中间态:锁定处理中数据 $waiting = ['status'=>0]; $lock = ['status'=>1]; $lock_res = $db->update('order_queue',$lock,$waiting,2); //每次刷新新处理2条 if ($lock_res){ //2. 对这些处理中数据进行配货 $res = $db->selectAll('order_queue',$lock); //配货代码... //3. 修改订单状态为已完成 $success = [ 'update_time' => date('Y-m-d H:i:s'), 'status'=>2 ]; $res_last = $db->update("order_queue", $success,$lock); if($res_last){ echo 'Success: '.$res_last; }else{ echo 'Failed'; } }
秒杀场景下的流量消峰:
【生产方】github
if ($redis->lLen($redis_name) < $num) { $redis->rPush($redis_name, $uid . '%' . microtime()); echo '秒杀成功' . $uid; } else { echo '秒杀已结束.'; }
【消费方】redis
sleep(2); $user = $redis->lPop($redis_name); if(!$user || $user=='nil'){ //为空判断 continue; }else{ $user_arr = explode('%', $user); $insert_data = [ 'uid' => $user_arr[0], 'rtime' => date('Y-m-d H:i:s'), 'req_time' => $user_arr[1] ]; echo '-'; $res = $db->insert('redis_queue',$insert_data); //数据库写入成功判断 if(!$res){ $redis->rPush($redis_name, $user); } }
可用于解耦、方便扩展
php-amqplib/php-amqplib: demo//publish.php、consumer.php
用法直接参考demo:sql
$exchange = 'router'; $queue = 'msgs'; $connection = new AMQPStreamConnection(HOST, PORT, USER, PASS, VHOST); $channel = $connection->channel(); $channel->queue_declare($queue, false, true, false, false); $channel->exchange_declare($exchange, AMQPExchangeType::DIRECT, false, true, false); $channel->queue_bind($queue, $exchange); $messageBody = implode(' ', array_slice($argv, 1)); $message = new AMQPMessage($messageBody, array('content_type' => 'text/plain', 'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT)); $channel->basic_publish($message, $exchange); $channel->close(); $connection->close();
# 本机搭建 git clone https://github.com/cffycls/cluster.git /home/wwwroot docker run --name rbt -p 5672:5672 \ --network mybridge --ip=172.1.12.15 \ -v /home/wwwroot/cluster/rabbitmq/rabbitmq.conf \ -v /home/wwwroot/cluster/rabbitmq/data:/var/lib/rabbitmq/mnesia \ -e RABBITMQ_ERLANG_COOKIE='123456' \ -e RABBITMQ_DEFAULT_USER=root -e RABBITMQ_DEFAULT_PASS=123456 \ -d rabbitmq
实例及数据库代码上传:
https://github.com/cffycls/msg_quedocker