核心结构
业务系统 =====> 消息队列 =====> 队列处理系统
业务场景
- 冗余数据:在某些订单系统中我们需要通过订单获取额外的信息并冗余到订单数据上但不需要实时获取时,可使用队列
- 系统解耦:出队系统与入队系统完全无关
- 流量削峰:秒杀与抢购等容易出现短期内流量剧增的场景
- 异步通信
- 扩展性需求
- 排序保证
队列介质
- MySQL:可靠,易实现,速度慢
- Redis:速度快,单挑大消息包时效率低
- 消息系统:专业性强,可靠,学习成本高
消息队列处理触发机制
- 死循环方式读取:易实现,实时性高,故障时无法及时恢复(秒杀场景)
- 定时任务:压力均匀,有处理量上限(配货系统)
- 守护进程:类似于PHP-FPM和PHP_CG,需要Shell基础
例子
下面以配货系统作为例子进行说明:
1. MySQL实现
首先需要在mysql中创建一个订单表,我们假定status为0时订单为代发货状态,status为1时订单为备货处理中,status为2时备货完成
CREATE TABLE `order` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`orderSn` varchar(20) COLLATE utf8_bin DEFAULT NULL,
`mobile` bigint(11) DEFAULT NULL,
`status` int(2) DEFAULT 0,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
下面是创建订单类
<?php
if(!empty($_GET['mobile'])){
$mobile = intval($_GET['mobile']);//手机号码不存在字母,可以使用intval进行过滤
$orderSn = rand(100000,999999);//简单的随机一个订单编号
$data = [
'orderSn'=>$orderSn,
'mobile'=>$mobile,
'status'=>0
];
$res=db->insert($data);//执行插入操作,请自行构建db类
if($res){
echo "订单创建成功";
}else{
echo "订单创建失败";
}
}else{
echo "请输入手机号码"
}
?>
接下来就需要实现我们的备货程序了
<?php
//配货处理程序主要分三步
//1.获取一条未处理状态的订单数据
//2.更新该数据为处理中
//3.处理数据并更新为已处理状态
//4.重复执行1.2.3
while(true){
$order = $db->query([ 'status' => 0 ]);//获取一条未处理数据
if(empty($order)){
echo "no data need operate";
continue;
}
//此处更新一条id为$order['id'],status为0的订单数据状态设定为1并获取更新结果
$res = $db->update([ 'id' => $order['id'] , 'status' => 0 ] , ['status' => 1 ]);
if(!$res){
continue;
}else{
//配货
//.....
$res = $db->update([ 'id' => $order['id'] ] , [ 'status' => 2 ]);//因为数据已经锁定,默认sql执行成功
echo "order ".$order['orderSn']." operated....";
}
}
?>
当我们把订单程序部署到nginx下或者apache下,就可以以单独的进程去执行咱们的配货程序了。当然你也可以对配货程序进行修改,使用crontab来执行定时任务
190

被折叠的 条评论
为什么被折叠?



