Web服务器何时开始执行请求?是否需等待完整请求接收完毕再处理?
Web服务器请求执行时机与你的业务场景解决方案
一、Web服务器执行请求的节点
常规LNMP(Nginx+PHP-FPM)、LAMP(Apache+mod_php)等PHP常用运行栈,默认都会等待接收完全部HTTP请求内容(包括上传的图片文件)后,才会将请求转发给PHP进程执行业务代码。
PHP里的$_POST、$_FILES等超全局变量,都是Web服务器收完完整请求后组装好再传入PHP runtime的,你的业务代码启动时,所有上传的文件已经完整存放在服务器临时目录中,不会出现代码执行到一半还在等待请求分片传输的情况。
只有你使用Swoole、Workerman等自定义服务端框架,主动开发流式分片处理逻辑时,才会出现边收请求边执行的情况。
二、你的业务原子性问题解决方案
你要求两个操作全部成功才算业务完成,推荐按优先级选择以下方案:
- 优先调整操作顺序:先完成图片缩放、存储的全部操作,确认成功后再执行MySQL数据插入。这是成本最低的方案,图片处理失败不会触发数据库写入,自然不会产生冗余数据。
- 如果业务逻辑不允许调整顺序,使用数据库事务回滚机制:把数据库插入逻辑放在事务中,只要图片处理失败,直接回滚事务即可清除已写入的无效数据,示例代码如下:
$pdo = new PDO('mysql:host=你的数据库地址;dbname=你的库名', '账号', '密码'); // 开启事务 $pdo->beginTransaction(); try { // 执行业务数据插入 $pdo->exec("INSERT INTO 业务表 (字段1, 字段2) VALUES ('val1', 'val2')"); $recordId = $pdo->lastInsertId(); // 执行图片处理存储逻辑 $imageProcessRes = imageResizeAndSave($_FILES['upload_img']['tmp_name'], '/target/path/'.$recordId.'.jpg'); if (!$imageProcessRes) { throw new Exception('图片处理存储失败'); } // 所有操作成功,提交事务 $pdo->commit(); } catch (Exception $e) { // 任意环节失败,回滚事务清除已写入的数据库数据 $pdo->rollBack(); // 错误日志记录、失败响应返回逻辑 }
- 应对断电、进程被强杀等极端异常(此时回滚代码无法执行),额外加定时垃圾清理脚本:定期扫描数据库业务记录,核对对应路径的图片是否存在,不存在则删除对应无效数据库记录即可。
内容的提问来源于stack exchange,提问作者Billie Jean
相关产品推荐
相关产品推荐

