php并发访问排队_PHP解决并发问题的几种实现

-对于商品抢购等并发场景下,可能会出现超卖的现象,这时就需要解决并发所带来的这些问题了.在PHP语言中并没有原生的提供并发的解决方案,因此就需要借助其他方式来实现并发控制。

#######方案一:使用文件锁排它锁

flock函数用于获取文件的锁,这个锁同时只能被一个线程获取到,其它没有获取到锁的线程要么阻塞,要么获取失败

在获取到锁的时候,先查询库存,如果库存大于0,则进行下订单操作,减库存,然后释放锁

flock()函数锁定或释放文件 若成功,则返回 true。若失败,则返回 false。

flock($fp,lock,block)

lock

共享锁定(读取) LOCK_SH

独占锁定(写入) LOCK_EX

释放锁定LOCK_UN

block 若设置为true 则当进行锁定时阻挡其他进程

注意

1.使用共享锁LOCK_SH,如果是读取,不需要等待,但如果是写入,需要等待读取完成。

2.使用独占锁LOCK_EX,无论写入/读取都需要等待。

3.LOCK_UN,无论使用共享/读占锁,使用完后需要解锁。

4.LOCK_NB,当被锁定时,不阻塞,而是提示锁定。

穿透到数据库,而使数据库奔溃,这里可用文件锁来解决

$data = $cache->get('key');

if(!$data){

$fp = fopen('lockfile');

if(flock($fp, LOCK_EX)){

$data = $cache->get('key');//拿到锁后再次检查缓存,这时可能已经有了

if(!$data){

$data = mysql->query($sql);

$cache->set('key', $data);

}

flock($fp, LOCK_UN);

}

fclose($fp);

}

#######方案二:使用MySQL数据库提供的悲观锁

Innodb存储引擎支持行级锁,当某行数据被锁定时,其他进程不能对这行数据进行操作

先查询并锁定行:

select stock_num from table where id=1 for update

if(stock_num > 0){

//下订单

update table set stock_num=stock-1 where id=1

}

#######方案三:使用队列

将用户的下单请求依次存入一个队列中,后台用一个单独的进程处理队列中的下单请求

1.创建队列数据表

2.把任务(比如 订单创建)插入队列表中

3.linux上做个定时任务,异步执行队列表中的任务,一个一个排队执行。

#######方案四:使用Redis/Memcached

redis的操作都是原子性的,可以将商品的库存存入redis中,下单之前对库存进行decr操作,如果返回的值大于等于0等可以下单,否则不能下单,这种方式效率较高

if(redis->get('stock_num') > 0){

stock_num = redis->decr('stock_num')

if(stock_num >= 0){

//下订单

}else{

//库存不足

}

}else{

//库存不足

}

其他并发问题:

在现实应用中,很多情况下会把数据存入缓存,当缓存失效时,去数据库取数据并重新设置缓存,如果这时并发量很大,会有很多进程同时去数据库取数据,导致很多请求

说白了,要解决并发问题就必须要加锁,各种方案的本质都是加锁

注释:

第一 首先,确认服务器硬件是否足够支持当前的流量。

第二 其次,优化数据库访问。

前台实现完全的静态化当然最好,可以完全不用访问数据库,不过对于频繁更新的网站,

静态化往往不能满足某些功能。

缓存技术就是另一个解决方案,就是将动态数据存储到缓存文件中,动态网页直接调用

这些文件,而不必再访问数据库,WordPress和Z-Blog都大量使用这种缓存技术。

如果确实无法避免对数据库的访问,那么可以尝试优化数据库的查询SQL.避免使用

Select * from这样的语句,每次查询只返回自己需要的结果,避免短时间内的大

量SQL查询。

第三,禁止外部的盗链。

外部网站的图片或者文件盗链往往会带来大量的负载压力,因此应该严格限制外部对

于自身的图片或者文件盗链,好在目前可以简单地通过refer来控制盗链,Apache自

己就可以通过配置来禁止盗链,IIS也有一些第三方的ISAPI可以实现同样的功能。当

然,伪造refer也可以通过代码来实现盗链,不过目前蓄意伪造refer盗链的还不多,

可以先不去考虑,或者使用非技术手段来解决,比如在图片上增加水印。

第四,控制大文件的下载。

大文件的下载会占用很大的流量,并且对于非SCSI硬盘来说,大量文件下载会消耗

CPU,使得网站响应能力下降。因此,尽量不要提供超过2M的大文件下载,如果需要

提供,建议将大文件放在另外一台服务器上。

第五,使用不同主机分流主要流量

将文件放在不同的主机上,提供不同的镜像供用户下载。比如如果觉得RSS文件占用

流量大,那么使用FeedBurner或者FeedSky等服务将RSS输出放在其他主机上,这

样别人访问的流量压力就大多集中在FeedBurner的主机上,RSS就不占用太多资源了。

第六,使用流量分析统计软件。

在网站上安装一个流量分析统计软件,可以即时知道哪些地方耗费了大量流量,哪些页

面需要再进行优化,因此,解决流量问题还需要进行精确的统计分析才可以。我推荐使

用的流量分析统计软件是Google Analytics(Google分析)。我使用过程中感觉其

效果非常不错,稍后我将详细介绍一下Google Analytics的一些使用常识和技巧。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值