商品秒杀,防并发解决思路

我们在做电商项目的时候,经常会遇到抢购秒杀的问题,综合来说主要是两个问题

一,高并发情况下对数据库产生的压力

二,如何避免超卖(库存< 0)的情况。

针对这两个问题来谈下解决思路

一,缓解数据库压力 用 缓存就可以解决 例如redis,memecache 等 就不在多说了。

二,解决这个问题有几种思路(推荐4redis)

1、将库存 goods_store 设置为 unsigned 则当小于0的时候则update失败

sql = update goods set goods_store=goods_store-1 where goods_store>0 and goods_id=11111

2、利用flock 文件排它锁

$fp = fopen(flock.txt, w+);

if (!flock($fp, LOCK_EX | LOCK_NB)) {

echo 系统繁忙稍后再试;

die;

}

下单.....

减库存......

3、使用数据库悲观锁(数据库开销比较大)

mysql_query(BEGIN);

$sql = select goods_store from goods where goods_id=11111 for update;

$res = mysql_query($sql, $conn);

$row = mysql_fetch_assoc($res,);

if ($row[goods_store] > 0){

$sql2 = update goods set good_store=goods_store-1 where goods_id=11111;

........

}

4、使用redis队列,因为pop操作是原子性的,即使很多用户到达也会依次执行,推荐使用(数据库悲观锁和flock在高并发情况下性能会下降很多)

①将库存存入redis

$amount = 100;

$redis = new Redis();

$res = $redis->connect(127.0.0.1, 6379);

$result = $redis->llen(goods_expensive);//查询已经消费掉的库存

$count = $amount - $result;//剩余库存

for($i=0; $i < $count; $i++){

$redis->lpush(goods_store,1);//遍历存入list

}

echo $redis->llen(goods_store);

②在下单前先判断库存量

$count=$redis->lpop(good_store);

if(!$count){

die(没有库存了);

}

$sql = update goods set goods_store=goods_store-1 where goods_id=11111;

库存减少成功.....

经验分享 程序员 微信小程序 职场和发展