导弹,最重要的能力之一就是对敌对核心目标进行精准打击,摧毁核心中枢,一个优秀的工程师也是如此,快速定位线上的BUG,透过代码看本质。之前有很多时候,不要改一个BUG,产生新的BUG,这也是高耦合的业务线最难搞和搞定的地方。总结一下自己解决问题的方法,希望大家下次再处理BUG时,可以从容面对。
client: 确定请求的IP和目标服务器
遇到问题,尤其线上问题,dev,test,web6,online配置和环境都是不同的,有的地方甚至有很多服务器负载。用ping
命令确认IP,或者是绑定本地的DNS
先确定问题的服务器IP目标。
ping http://blog.zhuangbfan.com/params.php?name=stark&age=30
也可以在浏览器查看IP和参数是否正确, 主要是定位你的url是否正确的定位到了目标服务器。如果有负载,自己在hosts
文件里确定访问到了指定的源目标服务器。
Request URL: http://blog.zhuangbfan.com/params.php?name=stark&age=30
Request Method: GET
Status Code: 200 OK
Remote Address: 101.200.87.200:80
Referrer Policy: no-referrer-when-downgrade
Query String Parameters(参数)
app_alias=com.xiaochundegushi03&uuid=49260f65006e509ac0605d7630d818c4&free_check=true
修改BUG一般都败在微小的细解里,有时候可能就简单到你访问的IP和程序的使用的配置文件不正确。
server: 服务器端的日志
nginx端的error_log 和 access_log
古代中国之文明之所以没有断层,都是因为有史官记录,log就是程序世界最好的记录者。web服务属于请求的上游,是所有程序的入口,是所有程序正确运行与否的源头,log往往最真实客观的反馈错误和异常的信息,是程序运行的第一反馈。
ps aux | grep nginx
看主进程master process
,有nginx的安装位置和配置文件的位置,在没有添加全局变量的时候查找nginx调起服务。
/usr/local/nginx/sbin/nginx -t #查看配置文件命令
/usr/local/nginx1_14_2/sbin/nginx -V #nginx安装路径和已安装的模块
Nginx的重要的有两个error_log
(web服务错误日志)和access_log
(web访问浏览日志),有很多时候,如果发生接口异常、超时、500、502先查看error_log
,将有助快速准确的解决问题,尤其是线上的问题,公共的接口出问题,影响是巨大的。
server
{
...
error_log /home/wwwlogs/nginx_error.log;
access_log /home/wwwlogs/zbf_error.log;
}
推荐两款好用的日志工具,Kibana 和 GoAccess,用图表很直观的方式去跟进、跟踪和反馈问题。
PHP中的 error_log
先找到php-fpm
的位置(有的服务器没有加入全局变量),看主进程的最后一项,主进程后面有配置文件的路径。
ps aux | grep php
使用命令找到php.ini的配置文件,修改error_reporting
、display_errors
、log_errors
、error_log
等参数配置。
/usr/local/php53/bin/php -i | grep php.ini
error_reporting定义错误报告级别,display_errors 这个参数是否输出错误,只要是线上就建议大家要关闭这个选项,输出的错误会暴露代码的位置,容易被黑客攻击。
error_reporting = E_ALL ; 将会向PHP报告发生的每个错误
display_errors = Off ; 不显示满足上条 指令所定义规则的所有错误报告
log_errors = On ; 决定日志语句记录的位置
log_errors_max_len = 1024 ; 设置每个日志项的最大长度
error_log = /var/log/php_errors.log; 指定产生的 错误报告写入的日志文件位置
php中的error_log也可以自定义错误,发送给服务、管理员、写入log中。
<?php
## error_log 函数
error_log("将错误消息写入到操作系统日志中", 0); //将错误消息写入到操作系统日志中
error_log("发送到管理员邮箱中", 1, ". mydomain.com"); //发送到管理员邮箱中
error_log("发送到本机对应5000端口的服务器中", 2, "localhost:5000"); //发送到本机对应5000端口的服务器中
error_log("发送到指定的文件中", 3, "/usr/local/errors.log"); //发送到指定的文件中
常用的线上修复BUG方法论
在以上查看log,还没有找到解决办法后,一般的web6(预上线)环境的部署环境和代码都是一样的,在web6上进行模拟BUG的出现或者方法,先泛读代码,了解大概处理的业务或者功能,看看是否复现,先看看是常规出现还是偶现的问题。
第二步在mysql中对比正常数据和错误数据的差别,看看数据是否一致,如果不一致,查看数据的更新逻辑是否正常,一般数据重复,关系表更新不同步、计划任务没有执行都可能会产生奇怪的问题。
查看缓存,因为是BUG,就有可能绕过了某段程序,没有走执行代码、或者没有更新缓存,导致的数据库存在,没有同步更新缓存。
PHP其他定位BUG的工具
Xdebug
xdebug是一个php中第三方的插件,在加扩展和参数,使用起来特别非常方便,xdebug主要起到调用回溯的作用,和debug_backtrace()作用相似,debug开头的函数有想深入理解的同学可以去文档上看看。
xdebug.auto_trace = On ;用于设定在脚本运行前是否自动跟踪方法的调用信息。
xdebug.show_exception_trace = On
xdebug.remote_autostart = On ;通常需要使用一个特定的HTTP GET / POST变量开始远程调试
xdebug.remote_enable = On ;这个开关控制Xdebug是否应该联系一个调试客户端监听的主机和端口的设置
xdebug.remote_host = 127.0.0.1 ; 选择主机的调试客户端运行时,可以使用主机名或IP地址。
xdebug.remote_port = 9000
xdebug.profiler_enable = on ;创建配置文件中的文件输出目录。
xdebug工具有很多设置的参数 是一款很方便快捷 跟踪脚本定位问题的超级好用的工具。
try…catch
php把执行过程中遇到的问题,分为错误和异常。错误就是reporting的报告等级,而异常在执行流程中可能会遇到的问题。try…catch就是预测并处理问题最常用的方法。
<?php
function inverse($x) {
if (!$x) {
throw new Exception('Division by zero.');
}
return 1/$x;
}
try {
echo inverse(5) . "\n";
echo inverse(0) . "\n";
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
// Continue execution
echo "Hello World\n";
?>
我理解的try…catch和魔术方法有相似的道理,都是把没有想到和程序缺陷走入设定好的执行逻辑中,使代码更健壮。
postman和curl
postman是一个很好用的测试接口软件,win和linux都支持的很好,可以添加文件夹,方便保存URL。
curl之前的博客里写的很多了,在这里就不赘述了。
欢迎喜欢的朋友,留言点赞,发财的小手走起来~