Yii 不支持原生负载均衡与 HTTP 并发;HttpClient 因未暴露 curl_multi_init 且采用单次绑定模型,无法实现 multi 并发,强行 patch 会导致 cookie、重试等功能失效,推荐改用 Guzzle Pool 方案。

Yii 本身不处理负载均衡,也不原生支持 HTTP 并发请求;高并发能力取决于你如何组合缓存、数据库策略、异步机制和外部基础设施。
为什么 Yii 的 HttpClient 不能直接 multi 并发
因为 yii\httpclient\Client 底层没暴露 curl_multi_init 接口,所有请求走的是单次绑定模型。常见错误包括调用不存在的 multiSend() 方法、手动塞 handle 后返回 null 或乱序响应。
它设计目标是链式构建 + 单次发送,不是高并发 HTTP 客户端。强行 patch cURL handler 会导致 cookie jar、重试逻辑、event hook 全部失效。
实际可用方案只有两个:
- 改用
GuzzleHttp\Client,配合Pool和concurrency控制并发数(推荐) - 在 CLI 环境下用
pcntl_fork或amphp模拟,并非 Web SAPI(如 FPM)下的可行路径
Schema 缓存不生效的典型原因
即使你在 config/db.php 里写了 'enableSchemaCache' => true,也常因以下任一条件失败而退化为无缓存:
-
cache组件未正确定义或未启用(比如 Redis 连接不通,但配置里仍写了yii\redis\Cache) -
schemaCacheDuration设为0或负数(此时等效于禁用) - 表结构被 ALTER 过,但缓存未主动清空,导致旧字段信息残留(尤其在开发环境频繁改表时)
验证是否生效:开启 MySQL 的 general_log,执行一条 User::find()->one(),看是否只出现一次 SHOW FULL COLUMNS FROM `user`。
读写分离配置后 SELECT 还走主库?
Yii 2 的 db 组件支持自动读写分离,但前提是查询必须满足「只读语义」。以下情况会绕过从库,强制走主库:
- 事务内任何查询(哪怕只是
SELECT),全部路由到主库 - 显式调用
createCommand()->setConnection($master)覆盖了默认行为 - 使用了
QueryBuilder手动拼 SQL,且未声明replication => false(某些复杂子查询会被误判为需写操作)
调试建议:在 slaves 数组里故意填一个错误 IP,如果请求报连接超时,说明读请求确实尝试走了从库;否则就是被上述条件拦截了。
Redis 缓存组件配错导致性能更差
把 cache 换成 yii\redis\Cache 不等于性能提升——配置不当反而引入新瓶颈:
- 未设
keyPrefix:多环境共用同一 Redis DB 时,测试/生产 key 冲突,缓存互相污染 - 连接池未复用:每次请求新建 Redis 连接(比如用了
yii\redis\Connection但没配maxConnections) - 大 Value 直接存 PHP 对象:序列化后体积膨胀,网络传输+内存占用双升,应优先用
asArray()+json_encode
关键点:Redis 是快,但网络 RTT 和序列化开销真实存在。热点数据用 get() 前先 exists() 判断,比盲取再判 false 更省资源。
真正卡住高并发的,往往不是框架上限,而是缓存键设计、SQL 关联方式、以及对「并发」二字的误解——比如在 FPM 下幻想靠 fork 实现 HTTP 并发,结果只触发了进程阻塞。细节决定吞吐量,而不是配置开关的数量。



















