yii适合高并发业务的前提是配置得当、代码规范、缓存到位;需关闭调试模式并确认yii_debug为false,将cache换为redis并配准schemacache,用with()预加载消灭n+1查询,同时启用opcache、优化mysql索引与连接配置。

Yii 适合高并发业务,但前提是配置得当、代码规范、缓存到位——它不是开箱即用就扛住万级 QPS 的“魔法框架”,而是给你足够多的高性能杠杆,就看你能不能全用上。
关掉调试模式并确认真正生效
YII_DEBUG = true 是生产环境最大的性能杀手。开着它,每个请求都会记录 SQL 执行计划、堆栈、变量快照,单请求多耗 20–40ms;高并发下日志写入还会触发文件锁,导致请求排队。
- 打开 web/index.php,顶部改为
defined('YII_DEBUG') or define('YII_DEBUG', false); - 全局搜索
YII_DEBUG,确保 config/web.php、common/config/main.php 等处没用define('YII_DEBUG', true)或$_ENV['YII_DEBUG'] = true覆盖 - 在任意控制器加
var_dump(YII_DEBUG); die;,访问必须输出bool(false);否则说明某处偷偷重置了 - 顺手检查日志目标:
Yii::getLogger()->getTargets(),删掉或禁用FileTarget,避免高频 I/O 拖慢响应
把 cache 组件换成 Redis 并配对 schemaCache
FileCache 在 Linux 下高并发会触发 flock() 锁;DbCache 若没建索引,查缓存就是全表扫描。Redis 是更稳的选择,但光换 class 不够,关键要配准。
- 在 config/components.php 或 config/web.php 中注册 Redis 缓存组件:
- 在 config/db.php 的 db 组件中启用 schema 缓存:
- 运行
php yii cache/flush-all清旧缓存,再访问一个带 ActiveRecord 的页面 - 执行
redis-cli keys "prod_v3_*",确认出现schemacache:user这类 key;没有就说明 schemaCache 没走通
消灭 N+1 查询与数据库瓶颈
列表页里写 $order->user->name,等于 1 次主查 + N 次关联查。20 条数据就是额外 20 条 SQL,哪怕每条 50ms,也白耗 1 秒。
- 控制器中必须显式预加载:
Order::find()->with(['user.profile', 'items.product.category'])->all() - 深层关联不用嵌套 with,直接链式写:
with(['user.profile.avatar']) - 库存扣减等核心操作,别只靠 PHP 层判断:
->forUpdate()加数据库排他锁,或用 Redis 分布式锁(SET stock_key 1 NX EX 5)防超卖 - 给 MySQL 表加好索引:联合查询字段、WHERE 条件、ORDER BY 字段都要覆盖;用
EXPLAIN看执行计划,避免全表扫描
PHP 与容器层必须做的几件事
框架调优只是上半场,底层环境不匹配,再好的代码也跑不快。
- 启用 OPcache:
opcache.enable=1且opcache.revalidate_freq=0(生产禁用时间戳校验) - Docker 部署时,
pm.max_children按内存设:512MB 容器 → 设为 12;推荐pm = ondemand - MySQL 关闭持久连接:
'attributes' => [PDO::ATTR_PERSISTENT => false],并调低wait_timeout=300 - AssetManager 路径硬编码到容器可写目录,比如
'basePath' => '/var/www/html/assets',并确保目录有写权限











