情景
上线分为 开始上线、上线中、上线结束三种状态
上线中,会收到有关php fatal error的报警。
当上线结束后,就不会收到有关php fatal error的报警了。今天来追究一下为什么会有这样的问题?
测试
1:写两个php文件,其中一个文件调用另一个文件
2:使用ab测试
3:上线脚本
线上文件
index.php
<?php
function __autoload($name) {
require_once($name . '.php');
}
$a = new banner();
echo $a->getBanner();
echo PHP_EOL;
banner.php
<?php
class banner {
public function getBanner() {
return 'banner';
}
}
//这个有许多注释的信息,保证这个文件很大
将要上线的文件
index.php
<?php
function __autoload($name) {
require_once($name . '.php');
}
$a = new banner();
echo $a->getBannerList();
echo PHP_EOL;
banner.php
<?php
class banner {
public function getBannerList() {
return 'banner list';
}
}
//这个有许多注释的信息,保证这个文件很大
上线脚本
#!/bin/bash
cp index.php.new index.php
cp banner.php.new banner.php
开始
第一步:模拟用户并发,发起请求
ab -c 1000 -n 100000 xxxx.com/index.php
第二步:执行上线脚本
第三步:观察php_error.log
[14-Apr-2017 11:23:03 Asia/Shanghai] PHP Fatal error: Call to undefined method banner::getBannerList() in /data/www/index.php on line 8
[14-Apr-2017 11:23:03 Asia/Shanghai] PHP Stack trace:
[14-Apr-2017 11:23:03 Asia/Shanghai] PHP 1. {main}() /data/www/index.php:0
结论
当执行上线脚本时
1:有一个这样的时刻,index.php已经上线,banner.php还未上线。
2:请求发送过来,新的index.php文件调用老的banner.php文件。
3:此时问题就会出现。
这是一个错误的上线流程。
应该这么做
假设代码放在/data/tags/目录下
/data/tags/1_0_0/代码
/data/tags/1_0_1/代码
1:/data/www 软链接 /data/tags/1_0_0
2:上线新的代码到/data/tags/1_0_1
3:切换/data/www 软连接到 /data/tags/1_0_1
重启nginx、php-fpm即可