PHP 项目的 env 文件替换方案
读完本文,宁宁组希望读者能从中了解到:
- .env 文件内容越多,服务资源消耗越大
- .env 的替换方案有很多,ini 文件其实与 .env 没有区别,扩展的形式可尝试,但是对扩展的稳定性有要求
- 要适当的选择 require/require_once
问题描述
基于 Lumen 框架开发的项目,5 台 8c16g 的 cvm,跑空接⼝,当 qps 达到 3600+ 时,cpu 就已经达到了 60%+。
问题分析
搭建 tidyways、xhprof、xhgui 性能分析平台,发现 cpu 时间的确发⽣在 php-fpm 上。仔细分析个别接口,发现 dotenv 重复执⾏ 560 次,消耗时间占⽐ 70%+。于是猜可能和 env 有关。
测试模拟
覆盖 env ⽂件,先清空,再使⽤下⾯的语句追加
1 |
|
使⽤ wrk 进⾏并发压测
1 |
|
测试结果

wrk 返回结果示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
wrk -d1m -t8 -c16 -s php.lua --latency --timeout=2s http://10.3.7.20
Running 1m test @ http://10.3.7.20
8 threads and 16 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 3.66ms 2.40ms 78.31ms 84.97%
Req/Sec 584.01 96.99 0.91k 71.88%
Latency Distribution
50% 3.03ms
75% 4.30ms
90% 6.23ms
99% 12.67ms
279176 requests in 1.00m, 74.00MB read
Requests/sec: 4649.39
Transfer/sec: 1.23MB
优化方案
从测试结果可以看出 .env 文件中数据条数越多,所带来的开销也越大。于是又对 env 替换方案进行了调研,大致结果如下:
相同压⼒情况下 Require once 结果更稳定,Yaconf (php扩展⽅案,也可测试 Zend_Config_Ini【未验证】) 与 Require ⽅案 latency 为 99% 时变化较⼤;
Require once 与 Require ⽅式对⽐,如果在同⼀个⽅法中多次使⽤结果有所不同(测试只在⼊⼝处调⽤⼀次)
如果被 Require 的⽂件中定义为常量,Require 会报重复定义,Require once 不会;
- 如果将 Require 的⽂件改成返回数组,那么灾难开始,耗时随着 Require 次数增加。

通过上述验证,最后 .env 的替换方案变成在 bootstrap 时先定义自己的加载 env 配置功能:
- 将所有配置写在 php 文件中,可返回数组
- 替换 Laravel逻辑中关于配置加载相关逻辑
- 读取上述 php 中的文件内容
- 设置数组中数据到进程的环境变量
方案成效
因业务复杂度较大,当前优化成交为资源节省 33+%。
PHP 项目的 env 文件替换方案
https://blog.isnap.cn/posts/60deaa5a/