PHP网站的高并发处理思路
最近处理一个类似一元购商城网站的支付环节,根据需求,需要在用户支付过程中满足如下条件:
1.用户可以选择,其购买的产品如果本期没有的情况下,自动进入下一期的购买。
2.多个用户同时购买同一期,同一个商品,且购买的数量,有的为购买剩余数量的部分,有的为购买剩余的全部。
3.整个流程一定要快。
这个需求和平常的支付不同,尤其是在处理购买同一期,同一个商品的时候,涉及到改商品进入下一期以及对下一期的购买。如果在商品进入下一期的过程中,另一个相同需求的用户提交了,如何处置。
这里,将重点的方面,进行一一阐释
1.多个相同的请求提交,如何处置
根据从网上找的资料,这种情况非常类似淘宝的秒杀,最常用的措施就是将用户的请求放到队列中,然后再出队。经过这样的操作,可以让请求一个个被处理。避免大量请求进入,后提交的请求被阻塞。实际操作中,需要用到redis 的list变量类型。
尽快使用队列,也只是避免多个请求同时进入。如果提交的请求相同,测试,还需要用到php和mysql 的锁机制。
PHP中的锁就是文件锁。MYSQL 的锁,主要有共享锁sharedlock和lock for update。
文件锁
文件锁,比较适合对某一段代码进行锁定,如果你希望某一个流程在执行的时候,只能一个请求执行。其他的请求等待。可以使用
mysql的锁
共享锁,允许其他进程查询,但是不允许修改。lock for update 不允许查询和修改。两者都为行级锁
共享锁,适合那些订单数据有需要修改。但是,订单中的信息需要查询的。尤其是那种分发到队列的异步请求。
lock for update 则适合更新比较快的订单,写完就不需要的那种.
2.数据表的修改慢于请求
实际应用中还存在相同的请求同时发送过来时,该条数据的修改速度过慢,也就是说,第一条请求还没有执行表的修改,第二条请求就开始了,这样,就容易造成第二条请求的数据不准确。比如说,第一条请求,用户希望购买剩余的所有产品,在表修改还没有完成时,第二条请求开始,用户还需要该买,但实际上产品已经没有库存了。执行第二条请求的时候,就会报错。
在这个时候,就需要缓存服务器进行记录每次购买后剩余的数量。实际操作中,需要增加一条对该剩余数量的判断,如果剩余数量没有了,则根据用户要求,如果希望购买下一期,则此时触发进入下一期,并购买。如果用户不希望进入下一期,则返回给用户信息。
3.让复杂的请求加快速度
最简单,直接的方法,就是将整个流程进行把控,那些部分是必须执行完成的,比如说,用户的购买记录写入,用户余额扣除,产品余额扣除等。还有一些流程用户看不到。也就是并不一定非常立即完成的,则可以发送到队列中进行异步处理,在执行异步处理中,需要做好失败的预防措施。
简单来说,本文讨论的主要是后端的PHP 处理高并发,主要是用到锁机制,缓存服务器,以及同步和异步队列。这些工具根据业务的特点和流程配合使用。另外,针对数据库和请求,还可以在配置上升级,增加数据库和进行负载均衡,不过,配置是一方面,最终还要落实到流程的控制。