真异步需任务必执行、可重试、有监控,如批量导出;伪异步仅需客户端快速响应、不关心结果,如记日志。fastcgi_finish_request属伪异步,消息队列才是真异步基石。

fastcgi_finish_request 不能当异步用,它只是“提前关连接”,后续代码仍在当前请求进程里同步执行,卡住就真卡住。
别从“学异步”开始,先搞清你要解决什么问题:是用户提交表单后等 3 秒才看到“成功”?还是并发拉 10 个 API 耗时太久?还是后台要发邮件+写日志+更新统计,但不想让用户干等?目标不同,方案天差地别。
先分清场景:你到底需要“伪异步”还是“真异步”
伪异步:客户端收到响应就完事,后续逻辑不管成败、不关心结果,比如记录访问日志、触发推送通知。
真异步:任务必须执行、要结果、可重试、需监控,比如订单支付回调处理、批量导出生成、邮件发送。
- 伪异步够用时,
fastcgi_finish_request()+ignore_user_abort(true)是最轻量的选择,不用装扩展、不改部署 - 真异步必须上消息队列(
RedisList /RabbitMQ/Kafka),否则失败无感知、重试无保障、堆积无告警 - 别用
exec("php worker.php &")模拟异步——没进程管理、没错误捕获、没资源限制,上线三天必出事
想用 Swoole 协程?先过这三关
Swoole 不是给 FPM 环境加个 go() 就能跑的。它只在 CLI 下生效,且对 I/O 函数极其挑剔。
- 必须在脚本最开头调用
Swoole\Runtime::enableCoroutine(),否则co::sleep()直接报错或静默失效 - 所有阻塞调用必须替换:
file_get_contents→co::readFile(),curl_exec→Swoole\Coroutine\Http\Client,PDO::query→Swoole\Coroutine\Mysql - 没手动启动事件循环(
Swoole\Event::wait()或Swoole\Coroutine\run()),go()注册的任务根本不会调度——脚本执行完就退出
ReactPHP / Amp 入门最容易踩的坑
它们依赖 EventLoop,但 Loop 不是“自动运行”的背景服务,而是你得亲手 $loop->run() 启动的主循环。
-
React\Http\Browser实例化时漏传$loop参数,请求永远不会发出,也不会报错,只会卡死 - 在
then()回调里调用$loop->stop(),会导致整个循环终止——哪怕还有 9 个请求没返回,也全丢弃 -
phpredis默认是同步阻塞的,即使用了 ReactPHP,也得配合phpredis4.0+ 的异步模式或换用react/redis
别跳过进程/线程的基本约束
多进程不是万能解药,pcntl_fork() 在 Windows 下不可用,FPM 下被禁用,Docker 容器里常因 PID namespace 限制失败。
-
pcntl_fork()后必须用pcntl_wait()或pcntl_waitpid()回收子进程,否则快速积累僵尸进程 - PHP 8+ 的
parallel扩展虽支持线程,但共享变量仍需parallel\Channel显式传递,直接读写全局数组大概率得到脏数据 - 所有子进程/线程内抛出的异常,默认不会冒泡到父进程,不显式
try/catch+log,等于黑盒执行
go() 或 $loop->run(),而是任务失败时怎么重试、数据不一致时怎么补偿、流量突增时怎么限流、日志分散在多个协程里怎么归并——这些不在语法里,藏在每个 if 分支和每行 catch 后面。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











