PHP:如何精准的定位和解决线上BUG

导弹,最重要的能力之一就是对敌对核心目标进行精准打击,摧毁核心中枢,一个优秀的工程师也是如此,快速定位线上的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_reportingdisplay_errorslog_errorserror_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之前的博客里写的很多了,在这里就不赘述了。


欢迎喜欢的朋友,留言点赞,发财的小手走起来~

上一篇:phpinfo中敏感信息记录


下一篇:vscode配置phpxdebug