系统管理员入门:排除故障( 二 )


缩小范围如果没有明显的问题,但你可以重现所报告的问题,那也很棒 。所以,你现在知道网站是慢的 。现在你已经把范围缩小到:浏览器的渲染/错误、应用程序代码、DNS 基础设施、路由器、防火墙、网卡(所有的)、以太网电缆、负载均衡器、数据库、缓存层、会话存储、Web 服务器软件、应用程序服务器、内存、CPU、RAID 卡、磁盘等等 。
根据设置添加一些其他可能的罪魁祸首 。它们也可能是 SAN,也不要忘记硬件 WAF!以及…… 你明白我的意思 。
如果问题是接收到第一个字节的时间,你当然会开始对 Web 服务器去应用上已知的修复程序,就是它响应缓慢,你也觉得几乎就是它,对吧?但是你错了!
你要回去尝试重现这个问题 。只是这一次,你要试图消除尽可能多的潜在问题来源 。
你可以非常轻松地消除绝大多数可能的罪魁祸首:你能从服务器本地重现问题吗?恭喜,你刚刚节省了自己必须尝试修复 BGP 路由的时间 。
如果不能,请尝试使用同一网络上的其他计算机 。如果可以的话,至少你可以将防火墙移到你的嫌疑人名单上,(但是要注意一下那个交换机!)
是所有的连接都很慢吗?虽然服务器是 Web 服务器,但并不意味着你不应该尝试使用其他类型的服务进行重现问题 。netcat 在这些场景中非常有用(但是你的 SSH 连接可能会一直有延迟,这可以作为线索)! 如果这也很慢,你至少知道你很可能遇到了网络问题,可以忽略掉整个 Web 软件及其所有组件的问题 。用这个知识(我不收 200 美元)再次从顶部开始,按你的方式由内到外地进行!
即使你可以在本地复现 —— 仍然有很多“因素”留下 。让我们排除一些变量 。你能用普通文件重现它吗? 如果 i_am_a_1kb_file.html 很慢,你就知道它不是数据库、缓存层或 OS 以外的任何东西和 Web 服务器本身的问题 。
你能用一个需要解释或执行的 hello_world.(py|php|js|rb..) 文件重现问题吗?如果可以的话,你已经大大缩小了范围,你可以专注于少数事情 。如果 hello_world 可以马上工作,你仍然学到了很多东西!你知道了没有任何明显的资源限制、任何满的队列或在任何地方卡住的 IPC 调用,所以这是应用程序正在做的事情或它正在与之通信的事情 。
所有页面都慢吗?或者只是从第三方加载“实时分数数据”的页面慢?
这可以归结为:你仍然可以重现这个问题所涉及的最少量的“因素”是什么?
我们的示例是一个缓慢的网站,但这同样适用于几乎所有问题 。邮件投递?你能在本地投递吗?能发给自己吗?能发给<常见的服务提供者>吗?使用小的、纯文本的消息进行测试 。尝试直到遇到 2MB 拥堵时 。使用 STARTTLS 和不使用 STARTTLS 呢?按你的方式由内到外地进行!
这些步骤中的每一步都只需要几秒钟,远远快于实施大多数“可能的”修复方案 。
隔离观察到目前为止,当你去除特定组件时无法重现问题时,你可能已经偶然发现了问题所在 。
但如果你还没有,或者你仍然不知道为什么:一旦你找到了一种方法来重现问题,你和问题之间的“东西”(某个技术术语)最少,那么就该开始隔离和观察了 。
请记住,许多服务可以在前台运行和/或启用调试 。对于某些类别的问题,执行此操作通常非常有帮助 。
这也是你的传统武器库发挥作用的地方 。strace、lsof、netstat、GDB、iotop、valgrind、语言分析器(cProfile、xdebug、ruby-prof ……)那些类型的工具 。
一旦你走到这一步,你就很少能摆脱剖析器或调试器了 。
strace 通常是一个非常好的起点 。
你可能会注意到应用程序停留在某个连接到端口 3306 的套接字文件描述符上的特定 read() 调用上 。你会知道该怎么做 。
转到 MySQL 并再次从顶部开始 。显而易见:“等待某某锁”、死锁、max_connections ……进而:是所有查询?还是只写请求?只有某些表?还是只有某些存储引擎?等等……
你可能会注意到调用外部 API 资源的 connect() 需要五秒钟才能完成,甚至超时 。你会知道该怎么做 。
你可能会注意到,在同一对文件中有 1000 个调用 fstat() 和 open() 作为循环依赖的一部分 。你会知道该怎么做 。
它可能不是那些特别的东西,但我保证,你会发现一些东西 。
【系统管理员入门:排除故障】如果你只是从这一部分学到一点,那也不错;学习使用 strace 吧!真的学习它,阅读整个手册页 。甚至不要跳过历史部分 。man 每个你还不知道它做了什么的系统调用 。98% 的故障排除会话以 strace 而终结 。


推荐阅读