PHP消息队列实现及应用:队列处理订单系统和配送系统

解耦案列:队列处理 订单系统和配送系统

我们在前面了解过消息队列的使用场景:
http://blog.csdn.net/github_26672553/article/details/78194336

这里,我们要来处理其中一个场景:系统的解耦。

在电商项目中,当客户提交了一个订单之后,客户在个人中心可以看到订单处于配送中。
这个时候就要参与进来一个系统,叫做『配送系统』。如果我们在做架构的时候,把订单系统配送系统设计在一起的话就会出现一些问题:订单系统的压力比较大,但是配送系统没有必要对这些压力做及时的反应;我们不需要订单系统出现故障之后导致配送系统故障。

所以我们需要把这2个系统分开,通过一个中间的队列表来实现这2个系统的沟通。

如下图架构:
这里写图片描述

具体到我们的程序代码大致逻辑如下图:
这里写图片描述

大致流程:order.php来接收用户订单,生成订单号并对订单进行处理(订单系统);在订单系统会把配送系统所需要的数据放入队列表中;我们的配送系统goods.php会有个定时脚本每分钟执行一次,处理队列表中的数据。

简单设计队列表order_queue

CREATE TABLE `order_queue` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `order_id` int(11) unsigned NOT NULL COMMENT '订单ID(从订单系统来的)',
  `user_info` varchar(255) NOT NULL DEFAULT '' COMMENT '可以是用户手机号/用户id等(这里只是演示)',
  `created_at` datetime NOT NULL COMMENT '订单创建时间',
  `updated_at` datetime NOT NULL COMMENT '本记录最后处理完成时间',
  `status` tinyint(2) NOT NULL COMMENT '0未处理,1已处理,2处理中',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

mysql订单队列

前面我们已经分析清楚了逻辑,剩下的就是代码实现了。
注意:我这里只是演示代码,单纯为了展示实现过程。

1、接收订单,处理订单order.php

<?php
// 这个文件是用来接收用户的订单信息 并写入队列的一个文件

if(!empty($_GET['user_info'])){
    // 验证 过滤 接收的数据 
    // todo...

    // 这里是应该首先是订单中心的处理流程
    // 因为订单系统是一套单独的系统 这里就不编写这个系统了
    // todo... 

    $order_id = rand(100000,99999); // 正常的订单号从 订单系统来,我们这里只是演示

    // 把配送系统需要的订单数据存入队列表中
    $insert_data = array(
        'order_id'=>$order_id,
        'user_info'=>$_GET['user_info'],
        'created_at'=>date('Y-m-d H:i:s',time()),
        'status'=>0
    );
    // 把上面的数据 插入到order_queue表中
    // insert into order_queue
}

2、配送系统goods.php

<?php
// 这个文件主要是配送系统处理队列表中的订单并进行标记的文件

//分析:
//第一步:先把要处理的记录更新为『等待处理』
//第二步:选择刚刚标记为『等待处理』的记录,然后进行配送系统的处理
//第三步:把上面前面处理过的程序标记『已完成』

/////////////////////这里很重要,你一定要明白哦//////////////////////////////////////////////
//疑问:为什么不直接处理最后更新为『已完成』,多了先标记为『等待处理』?
//这是因为配送系统很可能不是及时完成的,它中间会有一段处理的时间,如果还在处理中有其他程序来进行读取和操作,就冲突了。
//这样设计其实也是一个锁的机制

//1、
$waiting = array('status'=>0);
$lock = array('status'=>2);
//把状态为0的记录标记为2,每次更新3条(具体每次几条看情况)
$sql = "update order_queue set status=2 where status=0 limit 3";

//2、
if(上面update成功){
    // 选择出要处理订单内容
    // select * from order_queue where status = 2;

    // 然后由配货系统进行处理
    // todo...

    //3、处理完成把订单状态更新为已完成
    $success = array(
        'status'=>1,
        'updated_at'=>date('Y-m-d H:i:s',time())
    );

}else{
    echo 'All Finished';
}

3、linux服务器 定时任务

写个shell脚本:goods.sh

#!/bin/bash

date "+%G-%m-%d %H:%M:%S"
cd /var/www/
php goods.php

这个脚本就是去执行orders.php这个程序的。

在linux服务器部署定时任务:

crontab -e
*/1 * * * * /var/www/goods.sh >> /var/www/goods_shell.log 2>$1

每分钟执行一次goods.sh文件,并记录日志到goods_shell.log文件(在对应目录新建该文件)

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值