1.开发环境,nginx+mysql+Linux+php(thinkphp5)+redis。通过jmeter模拟并发场景。
模拟场景:500人同一时间抢购30部手机,不使用任何技巧,仅依赖常规写法。
public function sale_order(){
$user_id = mt_rand(1,100000);
$goods_info = Db::name('goods')->where('id',1)->find();
if($goods_info['goods_num'] <= 0){
return '商品已售罄';
}
$user_info = Db::name('wallet')->where('user_id',$user_id)->find();
if(empty($user_info)){
return '用户信息不存在';
}
if($user_info['money']<$goods_info['flash_sale_price']){
return '秒杀失败,余额不足';
}
$order_num = $this->get_order_num();
$order_info = [
'order_num' => $order_num,
'user_id' => $user_id,
'goods_id' => $goods_info['id'],
'num' => 1
];
$user_banlance = round(($user_info['money'] - $goods_info['flash_sale_price']),2);
Db::startTrans();
try{
Db::name('goods')->where('id',$goods_info['id'])
->setDec('goods_num');
Db::name('goods_order')->insert($order_info);
Db::name('wallet')->where('user_id',$user_info['id'])
->update(['money'=>$user_banlance]);
Db::commit();
}catch (\Exception $e){
$log_data = [
'log' => $e->getMessage(),
];
Db::name('log')->insert($log_data);
Db::rollback();
return '下单失败';
}
return '下单成功';
}
2. 这里是运行结果。
从以上结果可以看到,常规的写法里,导致商品超卖12个,有65.4%的请求没有得到正常响应。