Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

当你的程序(PHP,C/C++,Java,Python,Go等等)出错了,网络请求失败了,如何调试和定位? -- twin #9

Open
mingyun opened this issue Aug 26, 2014 · 0 comments

Comments

@mingyun
Copy link
Contributor

mingyun commented Aug 26, 2014

  1. 断点,error log. -- 零度西瓜
  2. 网络请求失败,比如404,500,cannot resolve host, 返回数据格式不正确等等 -- twin
  3. 分析程序日志,系统日志,各种系统网络路由器监控日志,再结合机房的配合 基本能搞定 -- Mandman
  4. 一步步定位,看是哪个环节出错,把php的error_reporting打开,fpm日志打开,nginx日志打开,tcpdump抓包看是否正常请求和到达 -- 星星
  5. 调试一个请求:b/s 用浏览器的network,如果有302的话可选择preserve log 或者用插件stop掉302;b/s的话可以tail -f查access.log 如需更详尽的请求信息可以用抓包工具fiddler、Charles 等。拿到请求后可在命令行下做调试(chrome 可以在networks右键得到curl)。高效率依赖于好工具,比如灵活使用用管道,查看json的话用:curl url | php -r 'var_dump(json_decode(file_get_contents("php://stdin"))); 还有更强大的jq: curl url | jq 。如果需要直接编辑可以用vim:curl curl | vim - 。而代码调试中经常用到二分打印,或者二分法分断删除再执行。 -- hilojack
  6. wireshark抓包分析 -- 杨锡坤
  7. if(isset($_GET['debug']))
    register_shutdown_function(function(){
    var_dump(error_get_last());
    }); //加在头部 无需修改任何配置 对程序无害 绿色 -- 吴子棋
  8. PHP firebug也不错啊 或者直接封装好函数输出<!—— print_r($var) ——> 查看源码 -- weizhao
  9. 先判断是否是网络故障了, ping 不同ip, dig 不同域名或路由, 检查防火墙, curl 测试不同链接, 如果不是网络问题, 就要看网络请求失败的具体header status, 是否404,301,302, 或500, 如果500, 则基本可以断定是对方服务问题, 比如请求某接口, 超过频率限制, 或对方服务已挂 -- 老李
  10. ping, telnet, dig, route, traceroute, iptables, curl, 基本上可以确定问题了 -- 老李
  11. 开发要掌握dns的原理, 为啥/etc/hosts 可以绑定域名, /etc/resolv.conf用来干啥, 主要理解dns是怎样工作的 -- 老李
  12. 如果linux防火墙端口没开,talent是不是也会通?
    答: 恩 -- 老
  13. 用户说你的网站打开太慢,请列出所有可能性,以及排查方法

一、网络问题

1、临时性
     检查:ping, mtr 等命令,检查网络状况,DNS等
     解决:联系机房或视具体情况而定

2、网络不同或距离太远
     检查:客户端和机房所在网络情况
     解决:双线机房或分布式部署,动态DNS,需要考虑成本

 3、资源加载慢
      检查:chrome控制台
      解决:CDN,合并请求,压缩页面代码等

二、前端问题

 1、浏览器太烂

 2、页面设计不佳
      检查:浏览器解析时间,是否DOM节点过多,JS有问题等
      解决:优化页面代码

三、服务端问题

1、服务器状态
      检查:负载,CPU, 网络,内存,磁盘空间等使用情况
      如果单台服务器性能受限,考虑调整为分布式架构,如nginx转发,DB分库分表等

 2、PHP响应慢
      检查webserver日志中的响应时间
      如果服务器整体负载不高,但PHP的数据返回时间过长,在PHP代码中分段输出处理时间
      更具环境的不同,可以选择直接输出或是写入日志
      如果是高访问量的在线调试,一般选取一定比例记录日志,防止日志过多带来的额外系统开销
      逐步缩小范围,定位、优化

 3、DB响应慢
      有分为读取慢和写入慢

      读取慢
      检查:慢查询日志;
                show processlist 查看当前DB状态,看哪些请求停留较多
                top查看mysql进程的开销
                代码中记录SQL和执行时间
      解决:
                手动执行可疑SQL(注意排除query cache的影响),用explain,profile等工具分析SQL性能
                再考虑是否优化索引,或者分库分表,或者增加缓存

      写入慢
      检查:除读取慢的检查方法外,还有
                iostat 检查磁盘IO
                查看mysql binlog的写入速率
      解决:增加缓存,分库分表,优化索引,从业务逻辑上考虑减少DB操作,合并写入

 4、其他
      被攻击,webserver进程数受限,甚至内网流量过高等原因,都有可能导致访问缓慢,具体情况具体分析

-- XiangZ

  1. 大家说了网络层面的,我说一下应用层面的吧,对于后端程序最靠谱的方法是看日志,因此代码里写日志就非常重要了,我这的后端产品都有全局的日志对象,每条日志记录编号、时间、类型、级别、执行经过时间、内容以及SessionID、请求编号、调用顺序号、访问渠道、用户编号、IP地址等标识请求方的字段,一般开发时的日志级别是Debug级别,线上运行时记录的日志级别是Error级别,可以通过配置指定特定的用户、IP地址的日志级别,比如某用户反映操作出错或相应很慢,排除网络问题后可以对该用户开启Debug级别的日志,通过日志定位问题。有两块日志是公共的,一是接口入口,记录接口的响应时间及未接管异常的错误信息、栈信息,二是统一封装的数据库模块记录的SQL执行日志,记录SQL响应时间及出错信息。 -- 水浸街
  2. 问: 线上不开debug有哪些原因呢? 为什么要分两块日志呢?sql出错也可以归到异常的

答: 日志记录本身是要消耗资源的,debug的信息非常多,所以不能开,当然性能允许也可以开。我说的两块日志是公共日志,就是不需要业务模块显式写日志的,实际写还是一个入口的。SQL出错的原因有很多,比如违反唯一性约束,这种情况下还是可控的,称为错误(error)合适一些,而异常则会引起程序流程终止执行,属于更高级别的错误(fault)。

  1. 对sql日志更多的应该还是一个审计,有没有异常,有没有慢sql. 要保障数据库的安全和稳定 -- 易元建
  2. 对,这是另一个功能,这里再次说一下SQL绑定变量,使用绑定变量除了可以提高效率,还可以保证一个系统的SQL语句的数量是有限的,可以从日志统计出各SQL语句的平均耗时,发现有问题的SQL语句 -- 水浸街
  3. 问: sql的error和fatal通过errorno区分? 那业务逻辑不就变复杂了吗?每次都得考虑各种code

答: 写日志不需要通过errorno区分,在入口try-catch捕获异常就可以了。 -- 水浸街

  1. 有个记log的形式叫cross finger。debug类型日志会先放内存里不落地 当出现error以上日志 就会把所有debug(包括之前未记录)也落地。这样可以更了解出错时的情况,减少让用户去重现的次数 -- twin
  2. log+strace+tcpdump+systemtap - 李奇
  3. 出错比请求慢定位方便。取出URL,手动请求,根据返回一点点下去,一般会很容易发现问题在哪。--7 Days
  4. 重点还是要log打的好 — 李秋林
  5. java,机器挂了有报警,业务出错有日志,有专门监控异常的系统定期分析异常原因,自己也有业务api工具线上出问题先看接口是否异常,然后再跟踪日志 — hello,zhuli

附加:
问:命名空间的好处是什么呢? — 李博
答:依赖管理和自动加载在下划线时代就有了 只是没现在这么成熟。 命名空间能做的,下划线基本都能做。
要说好处 我看到的是开源大佬不再顾忌长类名的问题,通过命名空间设计出更优秀合理的架构
symfony doctrine 都是用了命名空间后 类名变长 分层变细的例子 —twin

问:我们还在使用5.2.*这种版本的php。没有跟得很近。大家是否遇到什么强需求,会迫使或说主动使用更高版本的php? — 李博
答:一般也可以不升级,唯一担心就是将来很多开源代码都支持很多新特性,你老版本不能用,就会郁闷哦 — 黑夜路人
答:5.2太老了,PHP优秀的开源类库,大多用上了命名空间,要求最低5.3.3 — twin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant