JavaScript向Apache+PHP发起的异步请求未异步执行问题求助
排查生产环境Ajax请求串行返回的问题
这种生产环境偶发的串行请求问题确实让人头疼,结合你描述的场景(仅生产出现、预发布连同数据库正常、100个Ajax并发触发),我整理了几个不用依赖服务器调试工具也能尝试的排查方向:
优先排查PHP会话锁问题
PHP默认会在请求启动时锁定会话文件,直到请求结束才释放。如果你的每个Ajax请求都携带了PHPSESSID(默认行为),那这些请求会被强制串行处理——第二个请求必须等第一个释放会话锁才能读取会话数据。预发布环境可能因为测试并发量低、会话操作少没触发这个问题。
验证思路:在服务器端的API代码中,尽早调用session_write_close()——在完成所有会话相关的操作后立即释放锁,这样后续请求就能并行处理了。如果修改后问题消失,那就是会话锁导致的。排查数据库锁的生产环境特殊场景
虽然预发布连接同一数据库,但生产环境的数据量、请求并发度和事务场景完全不同。无索引的大表更新/插入确实会导致长时间锁表,但预发布可能因为数据量小没触发:- 如果有权限,临时开启数据库的慢查询日志,记录执行时间超过阈值的SQL,看是否有长时间运行的更新/插入语句;
- 尝试在数据库执行
SHOW PROCESSLIST,观察请求排队时是否有大量处于Locked状态的进程; - 对比预发布和生产的数据库事务隔离级别,更严格的隔离级别(比如REPEATABLE READ)可能导致锁范围扩大。
检查Apache的MPM并发配置
Apache的MPM(多处理模块)配置直接影响并发处理能力:- 如果生产环境用的是
prefork模式,MaxRequestWorkers(旧版本叫MaxClients)设置过小的话,100个并发请求会超出服务器的处理能力,超出的请求会被放到队列串行处理; - 对比预发布和生产的Apache MPM参数,重点看
MaxRequestWorkers、ServerLimit、MaxConnectionsPerChild这些配置; - 查看生产环境的Apache错误日志,有没有出现“server reached MaxRequestWorkers setting”这类警告。
- 如果生产环境用的是
验证客户端/网络层面的并发限制
虽然你说所有浏览器都有问题,但还是可以排除下特殊限制:- 浏览器对同一域名的并发请求有默认限制(一般是6个),但你看到的是完全串行,这不符合默认限制的表现,但可以尝试把请求分散到不同子域名(如果架构允许),看是否能恢复并行;
- 检查生产环境是否有企业级代理、防火墙或CDN,这些组件可能会限制并发请求数导致串行。
模拟生产负载复现问题
既然预发布连接同一数据库,你可以在预发布环境模拟生产的负载:- 用脚本(比如基于curl的批量命令、Python的requests库)发起100个并发请求;
- 往数据库插入和生产量级相近的测试数据,模拟真实的数据操作压力;
如果能复现串行问题,就可以在预发布环境安全调试,不用影响生产。
内容的提问来源于stack exchange,提问作者Emeeus
相关产品推荐
相关产品推荐

