多个应用中数据库连接错乱
1,情景描述
公司服务器现在十几二十几个项目,我们经常会发现,在多个基于laravel的web应用中,当应用A进行一个长时间操作时(PHP会运行超过30s+),在这期间,在应用B中进行数据库操作时,B应用会连接到A应用中的数据库,而非B的数据库
2,分析过程
2.1第一个猜想的是不是在B应用连接数据库时,直接使用的是A应用中连接数据库的资源,但是这种情况应该不会出现。
2.2laravel使用了vlucas/phpdotenv这个包来加载.env文件中的配置信息,具体的过程如下:
2.2.1,从.env文件中读取配置信息;
2.2.2,调用putenv()方法将配置信息设置到php环境中;
2.2.3,调用laravel封装的env()方法来读取配置信息(env()中其实调用了getenv()方法来配置信息读取);.env文件主要功能是为了在不同的部署环境实现不同配置,这样不同的环境可以共用同一套代码;
putenv()和getenv()是php4,php5,php7支持的用来设置和获取环境变量(environment variable)的方法。问题就出现在这里。
getenv()和putenv()不是一个线程安全的函数,意味着如果两个线程同时调用这个函数,就会出现问题。
而且服务器的环境正好是:
Apache + worker 模式,这种模式下,php运行环境是以线程模式运行的,所以才出现了上述的问题。
3.解决办法
3.1启用php进程运行模式(参照articles/dev/server/run_environments_for_php.md);
3.2将配置单独放在php配置文件中,这个可能造成硬编码,不过不推荐
3.3等待laravel修复这个问题。
5,或者大家有没有遇到过这个问题,交流一下解决办法~。