必须换成 redis 或数据库存储,因 filesession 在多机部署时无共享机制、i/o 瓶颈明显、扩容不友好;redis 响应快且支持自动过期,数据库方案需确保 id 字段为主键+索引。

Yii 2.0.50 默认用文件存 session,多机部署时会直接失效——用户请求被负载均衡分到不同服务器,各自读不到对方的 session 文件,登录态瞬间丢失。这不是性能问题,是功能不可用。必须换成 Redis 或数据库存储,才能保障会话一致性,响应速度也会随之稳定提升。
为什么必须换掉 FileSession
文件 session 在单机开发环境没问题,但一上生产就暴露本质缺陷:
- 无共享机制:每台服务器只认自己的
runtime/sessions/目录,跨机器无法同步 - 高并发下 I/O 瓶颈明显:大量 session 文件读写竞争磁盘,页面加载延迟上升
- 扩容不友好:加机器后 session 不自动迁移,用户反复登录
用 Redis 替换 session 存储(推荐)
Redis 响应快、支持过期自动清理、天然适合分布式场景。配置三步到位:
- 确认 PHP 已启用
php-redis扩展(不是 predis),否则启动报Class 'Redis' not found - 在
config/web.php的components中定义 redis 组件:
'redis' => [ 'class' => 'yii\redis\Connection', 'hostname' => '127.0.0.1', 'port' => 6379, 'database' => 0,],
- 再配置 session 组件,关键点是类名和 redis 实例名必须匹配:
'session' => [ 'class' => 'yii\redis\Session', 'redis' => 'redis', // 必须与上面组件名一致 'keyPrefix' => 'yii2_session:', // 避免 key 冲突],
改用数据库存储(兼容 Yii 2.0.50)
如果暂时没 Redis,数据库方案也可靠,但注意结构细节:
- Yii 2.0.x 使用
yii\web\DbSession,建表 SQL 必须含三个字段:id(VARCHAR(128),主键+索引)、data(LONGTEXT)、expire(INT) - 别直接套网上旧 SQL,id 缺少主键或索引会导致高并发下锁表严重,登录页卡死
- 配置示例:
'session' => [ 'class' => 'yii\web\DbSession', 'db' => 'db', // 指向已配置的数据库组件 'sessionTable' => 'session',],
验证是否生效
别只看“还能登录”,要查底层存储才真正确认:
- Redis 方案:连上 Redis,执行
KEYS yii2_session:*,能看到带 session ID 的 key;再GET一个,值是序列化字符串 - 数据库方案:查
SELECT * FROM session LIMIT 1,data字段非空且长度明显大于 100 字节(说明存了真实会话数据) - 最直白方法:临时把
'class'改成不存在的类名(如'yii\web\FakeSession'),刷新页面报错即说明配置已加载











