php高并发需靠架构优化而非语言本身:采用异步队列剥离耗时操作,合理配置php-fpm与opcache,数据库读写分离、预扣减库存、避免阻塞i/o,提升资源复用效率。

PHP本身不擅长高并发,得靠架构补足
PHP是同步阻塞模型,每个请求独占一个进程或线程(取决于SAPI),fpm下默认用pm = dynamic时,最大并发数直接受pm.max_children限制。1000+并发不是调大这个值就能解决的——内存会撑爆,响应延迟飙升,还可能触发系统OOM Killer。真正的瓶颈不在PHP代码快不快,而在I/O等待、数据库连接、锁竞争和资源复用效率。
必须把耗时操作从PHP主流程剥离
用户点击下单,你不需要在$_POST接收后立刻查库存、写订单、发短信、推消息。这些该交给异步队列。
- 用
Redis的LPUSH+BRPOP或pub/sub做轻量级任务分发 - 用
RabbitMQ或Kafka承载高可靠、有序、可重试的任务流 - PHP-FPM里用
fastcgi_finish_request()提前返回HTTP响应,再继续处理日志、埋点等非关键路径 - 避免在
__destruct或register_shutdown_function里做网络请求——FPM worker可能已回收资源
数据库是高并发下最常崩的环节
单个MySQL实例扛不住大量SELECT ... FOR UPDATE或高频INSERT。常见误操作包括:用UPDATE users SET balance = balance - 100 WHERE id = 123扣余额(没加唯一索引+条件校验,超卖)、在事务里做cURL调第三方(锁表时间翻倍)。
- 读写分离:用
mysqli或PDO手动路由,或用ProxySQL自动分流 - 查询走
EXPLAIN确认是否命中索引;WHERE条件含函数(如DATE(created_at))会导致全表扫描 - 库存类场景改用「预扣减」:先
INSERT INTO stock_log (order_id, sku_id, delta) VALUES (?, ?, -1),再异步核对并更新总库存 - 避免
SELECT COUNT(*) FROM huge_table——用缓存值或近似统计
PHP层面能做的有限,但几个配置必须调
别迷信“优化PHP代码能提升并发”,实际收益远不如压测后精准调整FPM和OPcache。
立即学习“PHP免费学习笔记(深入)”;
-
opcache.enable=1且opcache.validate_timestamps=0(上线后手动opcache_reset()) -
pm.max_children按内存算:假设每个worker占40MB,机器有4GB空闲内存,则设为100左右,而非盲目设500 -
pm.start_servers和pm.min_spare_servers设为相同值,避免突发流量时频繁fork新进程 - 禁用
session_start()除非真需要——它默认用文件存储并加锁;改用redis存储且设置session.save_handler = redis
真正卡住高并发的,往往不是某行foreach写得不够快,而是没意识到file_get_contents('http://api.x')这种调用会让整个worker阻塞3秒。拆IO、压队列、减锁粒度、缓存穿透防护——这些比纠结isset()还是array_key_exists()重要得多。











