同一服务器下部署多个 Laravel 项目可能导致 .env 相互影响

老牛浏览 572评论 0发表于

1. 前言

最近在开发单点登录(Single Sign On)时,本地部署了多个 Laravel 项目,结果在获取缓存数据时出现异常。SSO 服务端获取缓存是正常的,在 SSO 客户端通过 HTTP 请求获取 SSO 服务端返回的缓存值时一直不对,排查了很长时间,后来发现是 .env 环境变量互相影响,出现「串值」的情况。

2. 分析

这个问题多半发生在 Apache 上,因为加载 .env 文件的时候用了 getenv()setenv()。这两个函数不是线程安全的,它会将 .env 文件里面的值设置在进程级别的环境中(process-wide variable)。Apache 使用线程处理请求,当一个进程同时有几个线程的时候,就比较容易发生「串值」的情况。这是 一个「串库」的例子

不过这种情况在 PHP-FPM + Nginx 上面好像并不怎么会受影响(我搜索相关问题时,问题提到环境都是 Apache,没有找到 Nginx 的案例),因为 Nginx 使用进程来处理 PHP 请求,进程间相互独立,所以就算 getenv()setenv() 将变量设置在进程环境中,也没有太大影响,不会「串值」。可以参考 这里

This issue is related to a webserver hosting several requests within the same process. This causes problems with other things too, like setlocale(). Other configurations, like nginx + php-fpm, is not affected by this problem since it executes one process per request.

另外很多人建议由于 getenv()setenv() 不是线程安全的原因,生产环境不要使用 .env 文件,对于 Laravel 应用来说,应该执行 php artisan config:cache 对配置文件进行缓存,尽量避免使用 env() 函数。

3. 结论

部署 Laravel 应用时,推荐使用 Nginx 服务器,并执行 php artisan config:cache 对配置文件进行缓存,尽量避免使用 env() 函数。


参考资料:

点赞
收藏
暂无评论,快来发表评论吧~
私信
老牛@ilaoniu
老牛,俗称哞哞。单纯的九零后理工小青年。喜欢折腾,爱玩,爱音乐,爱游戏,爱电影,爱旅游...
最后活跃于