请问用Laravel做的商城,支付过程遇到高并发情况导致订单状态未处理成功 应采用哪些方案?

1. 运行环境

1). 当前使用的 Laravel 版本?

Laravel 5.4

2). 当前使用的 php/php-fpm 版本?

PHP 版本:7.3

php-fpm 版本:

没查到具体的版本。。如图

请问用Laravel做的商城,支付过程遇到高并发情况导致订单状态未处理成功 应采用哪些方案?

3). 当前系统

CentOS 8

4). 业务环境

开发环境,暂未加入负载均衡

5). 相关软件版本

2. 问题描述?

其实是之前的一个其他PHP 框架的项目,在短时间内大量用户进行支付的时候,钱都扣了,但是程序没有将订单状态改为已支付,导致会员开通失败。

3. 您期望得到的结果?

尽可能的让大量用户(比如一万人)同时进行支付时,确保订单信息不错乱。

4. 您实际得到的结果?

在短时间内大量用户进行支付的时候,钱都扣了,但是程序没有将订单状态改为已支付,导致会员开通失败

@李山河
你看我吊吗啊
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 39
Complicated

没用redis吗?

2年前 评论
你看我吊吗啊 (楼主) 2年前
Complicated (作者) 2年前
你看我吊吗啊 (楼主) 2年前
KayuHo

这可以理解为服务器需要支撑1w qps 了吧,单机怎么可能做得到

2年前 评论
你看我吊吗啊 (楼主) 2年前
荒街! 2年前
你看我吊吗啊 (楼主) 2年前

如果是遗留问题,你不想去改业务代码,最简单的解决方案如下:

  1. 随机拒绝,用户发起支付时随机生成一个 0~100 的数字,小于 10 才有支付资格,否则支付失败,具体颗粒度自己调整。
  2. 给产品添加 updated_at 字段,使用乐观锁,在查询产品信息时,如果 stock > 0,更新库存,更新库存的时候添加 where 字段,条件是 updated_at 字段与查询产品信息时相同,如果相同,更新时间戳,并且扣掉对应库存,否则直接支付失败。
    $product = Product::where('stock', '>', 0)->find($product_id);
    if(! $product->where('updated_at', $product->updated_at)->decrement('stock'))
    {
     throw new Exception "购买失败";
    }

每次更新 stock 时自动维护 updated_at 时间戳就好了。

2年前 评论
MArtian (作者) 2年前
你看我吊吗啊 (楼主) 2年前
MArtian (作者) 2年前
你看我吊吗啊 (楼主) 2年前
MArtian (作者) 2年前
李铭昕

用 Hyperf 重写这块

2年前 评论
lun1bz 2年前
你看我吊吗啊 (楼主) 2年前
huchao399 2年前
lun1bz 2年前
李铭昕 (作者) 2年前

redis应该可以解决绝大部分问题。

2年前 评论
orange1994

用队列吧

2年前 评论

支付成功,状态没变?是回调后,没有处理吗?

2年前 评论
你看我吊吗啊 (楼主) 2年前

可以简单一些,在调起支付的时候,用redis做个限流,这样的话,回调的数量就大概在可控范围了。如果硬性要求必须支持大流量的话,那就加服务器,负载,换Hyperf 、easyswoole 框架或者go来重写这块业务

2年前 评论
你看我吊吗啊 (楼主) 2年前

回调验签成功后放到队列处理其他更新状态等的逻辑

2年前 评论

上个队列就可以满足需求了,laravel 自带的 databases队列,或者redis队列,支付成功后,把付款成功写入队列,开两个work进程去消费队列就好。你的问题是付款成功了,但是权益没有加上,使用队列最合适了

2年前 评论

在异步回调那里加个队列应该够了...

2年前 评论
陈先生

Redis SetNx

2年前 评论

状态没修改说明异步回调没执行成功,回调可以放队列里处理,嫌速度慢就多开几个线程,我觉得更多是你服务器的瓶颈,配置太低了

2年前 评论
你看我吊吗啊

对,有支付记录,但是支付状态没改成功,异步回调里没处理好。

2年前 评论

redis的锁加一个,然后走队列,不行的话再加mq

2年前 评论
GDDD

商场类型的下单支付后,必须放到延迟队列里面去查询支付是否成功,及时,1分钟,3分钟 6分钟 10分钟...

2年前 评论
你看我吊吗啊 (楼主) 2年前
GDDD (作者) 2年前
你看我吊吗啊 (楼主) 2年前

异步回调放队列,另外我们在订单详情和列表会去查询微信支付状态,根据查询结果改状态

2年前 评论

后端对下单这个地方限流。 订单加个中间状态,比如 “正在处理中” 。然后 微信的回调请求的参数 ,加入队列里处理。处理完再改为已支付等。

2年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!