
最近处理一个后台接口时遇到一个比较容易误判的问题:用户点击执行任务,前端等了几十秒后提示请求超时,但过一会儿刷新页面,却发现任务其实已经执行成功了。有些用户看到报错后又点一次,结果同一批数据被处理了两遍。
最开始以为是 PHP 超时以后程序就会停止,实际排查日志才发现,浏览器断开连接和服务端 PHP 停止执行并不是一回事。前端请求虽然已经超时,Nginx 也可能结束等待,但 PHP-FPM 里的脚本仍然在继续执行后面的数据库查询、文件处理或者第三方接口请求。
后来把耗时操作从普通接口里拆了出来。用户点击后,接口只负责生成一条任务记录并立即返回任务编号,真正的数据处理交给后台任务执行。页面通过任务状态判断处理中、成功还是失败,重复点击时也会先检查同一任务是否已经存在,避免再次提交。
同时给每个任务增加开始时间、结束时间、执行结果和异常日志。这样即使后台处理几分钟,前端也不需要一直保持 HTTP 请求。
现在做批量处理、文件生成、数据同步这类耗时功能时,我一般不会让一个 PHP 请求从头跑到尾。接口响应时间和业务执行时间最好分开处理,不然一旦网络慢或者前端超时,很容易出现"页面说失败,后台却已经执行"的情况。
#PHP开发 #接口超时 #后台任务 #系统开发