Skip to content

性能优化

店铺访问慢、后台卡得要死?多半不是你网速差,也不是服务器不行。

慢在哪

罪魁祸首是 PHP 的 session 文件锁。

Web 服务器不是单线程跑你的 PHP 代码,而是多个工作进程同时处理请求。浏览器打开一个页面时,会并行去下载页面里引用的各种资源,于是同一个用户瞬间就产生了好几个并发请求。

而 PHP 的 session_start()阻塞,一直等到上一个请求的脚本调用 session_write_close() 释放为止。在 Linux 上它靠 flock() 实现。

结果就是:本来能并行的请求,被 session 锁排成了一队,一个接一个地跑。页面上资源越多,感觉越卡。

这个锁是必须的 —— 没有它,多个进程同时读写同一份 session 数据会互相覆盖,登录状态就会莫名其妙丢失。问题不在于有锁,而在于锁的介质是文件。

解决办法:把 session 换成 Redis

只要三步,效果立竿见影。

1. 装 Redis

宝塔用户:软件商店 → 搜索 redis → 安装。

其他环境按自己系统的方式装即可。

2. 给 PHP 装 redis 扩展

宝塔用户:软件商店 → 你的 PHP 版本 → 设置安装扩展 → 选 redis 安装。

3. 把 session 存储改成 Redis

宝塔用户: PHP 管理界面 → Session 配置 → 存储模式改成 redis → 保存。

没有面板: 编辑 php.ini

ini
session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6379"

; 如果 Redis 设了密码,用下面这行替代上面那行
; session.save_path = "tcp://127.0.0.1:6379?auth=你的redis密码"

改完重启 PHP,然后打开你的店铺 —— 差别会非常明显。

Docker 用户

镜像里已经带了 Redis,不用做任何配置,开箱就是 Redis 会话。

接的是外部 Redis 的话,启动容器时加上 -e ACG_REDIS_HOST=你的地址 即可,见 Docker 安装

虚拟主机用户

很遗憾,虚拟主机一般装不了 Redis,也改不了 php.ini,这个优化用不上。

程序当初没有强制用 Redis 做会话存储,正是为了让虚拟主机用户也能跑起来。功能不受影响,只是快不起来。

还有一个坑:配置缓存

如果某个配置项不在数据库里,程序每次请求都会去查一次库、并且加排他锁。在网络挂载(比如 CIFS)上,这会把全站请求串行化,比 session 锁还惨。

现象是站点莫名其妙全局变慢。遇到这种情况,检查一下 runtime/config 是否完整。

不要手动删 runtime/config 删它会让整站出问题。清模板缓存只删 runtime/view/compile

其他能做的

做法效果
开 opcachePHP 不用每次重新编译,明显提速
上 CDN静态资源走 CDN,但注意配好真实 IP 获取方式,否则拿到的全是 CDN 的 IP
定期清理订单订单表太大时后台列表会变慢

基于 MIT 协议开源