“网站慢”是一句描述,不是一个诊断。它可能是服务器离用户太远,也可能是数据库查询卡在磁盘上,还可能只是首页挂了一张8MB的图片。线路的问题要换线路,磁盘的问题要换磁盘,图片的问题连服务器都不用动,而把三者都归到“香港云主机不行”上,后面所有的调整都是白费力气。
这篇文章的做法是先建立诊断的顺序,再按网络、计算、Web服务、页面资源、路由这五个方向逐个定位。每一步都给出可以直接执行的检查办法。
同样叫慢,表现不同,方向就完全不同。先对照下面五种现象,看自己属于哪一种:
SSH或远程桌面连接慢。多半指向网络路径、丢包,或者防火墙。不过SSH登录慢有时和服务器端的DNS反查、认证设置有关,不全是网络问题,所以别急着下结论。
首页打开慢,但服务器连接正常。问题大概率在网站这一层:Web服务、应用程序、数据库,或者页面本身。
首次访问慢,第二次访问快。这通常是缓存的问题,包括服务器端缓存没有预热、CDN没有命中、DNS缓存,而不是线路本身。
国内访问慢,海外访问正常。这是典型的跨境路由或者目标运营商的问题,需要从多个地区、多个运营商分别测试。
页面能打开,但数据库查询或后台操作迟缓。把注意力放在数据库、磁盘I/O和查询语句上,线路在这里的嫌疑很小。
不同的现象,排查的方向不同,不能统一归因于线路。要把“慢”量化,最方便的办法是用curl把一次访问拆开,看每个阶段花了多久:
curl -o /dev/null -s -w "dns:%{time_namelookup} connect:%{time_connect} ttfb:%{time_starttransfer} total:%{time_total}\n" https://example.com
dns是域名解析耗时,connect是建立连接耗时,ttfb是收到第一个字节的时间,total是整个请求的总耗时。connect偏高,说明网络路径上有问题;connect正常而ttfb很高,说明服务器处理得慢;ttfb正常但total很高,说明内容本身传输得慢,比如页面或者文件太大。
先看带宽的上限是多少,实际的吞吐是多少,流量有没有用完。服务商控制台里一般有带宽和流量的监控曲线,服务器上也可以用nload、iftop或vnstat实时查看。
接着要区分两种看起来相似的情况:带宽不足,和网络丢包。带宽不足时,曲线会长时间贴着上限,形成一条平顶;丢包则不同,带宽可能根本没有跑满,但是页面依然卡顿,TCP重传的数量明显增多。重传情况可以这样看:
netstat -s | grep -i retrans
还要留意是否在高峰时段持续拥塞,把一天里不同时间的曲线放在一起看。如果网站以图片、视频或者大文件下载为主,评估一下是否需要CDN,把大流量从源站分担出去,比单纯加带宽更省钱。
扩容之前,先定位到底是哪一项资源成为了瓶颈,否则升了CPU,卡的却是磁盘,钱花了问题还在。几个常用的命令:
top # CPU持续使用率与占用最高的进程
free -h # 内存和swap的使用情况
vmstat 1 # 观察si/so,数值持续不为0说明在频繁换页
iostat -x 1 # 磁盘I/O:关注await和%util(需安装sysstat)
dmesg | grep -i oom # 是否发生过内存不足导致进程被终止
CPU长期处于较高水平,并且是某个进程占用,应该先去优化这个进程;内存不足会让系统把数据换到磁盘上,一旦频繁换页,整台机器都会明显变慢;磁盘方面,I/O等待高、数据库写入频繁、日志增长过快,都会拖慢动态网站。查清楚瓶颈,再决定是升配置,还是优化程序。
这一层没有一套所有机器通用的参数。小内存的实例,不应该机械地套用面向高并发服务器的配置,否则服务本身就会把内存吃光。下面只讲检查的思路。
Web服务的工作进程。Nginx可以先看worker_processes是否设置合理(一般设为auto,随CPU核数调整),Apache则看所选的工作模式以及最大连接数。
PHP和应用的并发能力。以PHP-FPM为例,max_children决定了同时能处理多少请求。设置的依据是内存:可用于PHP的内存,除以单个PHP进程的平均占用,得出大致的上限。设得过大,内存不够会引发换页甚至崩溃;设得过小,请求要排队。数据库的最大连接数也是同样的道理。
慢查询和索引。数据库慢,常常是少了一个索引。先打开慢查询日志,找出耗时的语句,再用EXPLAIN分析它的执行方式:
# MySQL / MariaDB 配置示例
slow_query_log = 1
long_query_time = 1
-- 分析某条慢查询
EXPLAIN SELECT ...;
缓存。根据业务选择:页面缓存,把整个页面的结果缓存起来;对象缓存,比如用Redis缓存数据库查询的结果;反向代理缓存,让Nginx直接返回缓存内容。WordPress这类站点,加上缓存之后,响应时间常常有明显的下降。
先确认DNS解析指向了正确的服务器,用dig检查返回的IP是不是预期的那一个,也要留意解析有没有指向旧的服务器。
接着打开浏览器的开发者工具,切换到网络面板,刷新页面,看每一个资源的加载时间。哪一项最耗时,一眼就能看出来:是一张过大的图片,还是体积庞大的脚本,或者是一个加载很慢的第三方资源。对于图片、CSS、JavaScript这类适合缓存的静态资源,应该设置合适的缓存策略,让浏览器不必每次都重新下载。
如果使用了CDN,要检查回源和缓存命中的情况。命中率低,说明大部分请求仍然回到了源站,CDN没有真正分担压力。很多CDN会在响应头里标注是否命中缓存,具体的字段名因服务商而异。
最后要区分两种问题:源站响应本身慢,和用户到CDN节点的连接慢。前者要去优化源站,后者则和CDN的节点覆盖、用户的网络有关,处理的方向不同。
当前面几项都没有发现异常,而且问题集中在特定的地区或者运营商时,再来看网络路径。用mtr可以同时看到路径上每一跳的延迟和丢包:
mtr -rwc 100 目标IP
同时检查防火墙和安全组,看是否有规则误伤了正常的访问,比如限制了某些来源,或者对连接数做了不合理的限制。
如果业务用到了隧道、VPN或者特殊的网络配置,才需要针对性地排查MTU。可以用带“不分片”标志的ping测试,找到链路上能通过的最大数据包:
# Linux
ping -M do -s 1472 目标IP
# Windows
ping -f -l 1472 目标IP
如果测试提示数据包需要分片,说明路径上的MTU小于1500,逐步减小数值,直到能通,再据此调整。这里要强调一个原则:不要没有证据就随意修改MTU,不要为了“试试看”就关闭防火墙,更不要放开所有的端口。每一次修改,都应该有对应的测试结果作依据。最后,别忘了对比不同时间、不同运营商和不同地区的访问情况,单一时间点的结果容易误导。
把上面的内容压缩成一张表,遇到问题时对照使用:
故障表现 | 优先检查方向 | 判断依据 |
SSH登录慢 | 网络路径、丢包、防火墙;服务器端的DNS反查和认证设置 | 不同地区、不同运营商的连接情况,mtr的丢包与延迟 |
页面整体慢 | 网络、源站负载、Web服务 | 首字节时间(TTFB)与服务器资源占用 |
只有数据库操作慢 | 数据库、磁盘I/O、索引 | 慢查询日志及磁盘I/O指标 |
大文件下载慢 | 带宽、并发、缓存 | 实际吞吐曲线与传输中断情况 |
国内慢、海外较快 | 跨境路由、目标运营商 | 多地区、多运营商的测试结果 |
首次访问慢、再次访问快 | 缓存预热、CDN回源、DNS缓存 | CDN命中情况与响应头中的缓存标记 |
先确定故障出在服务器内部,还是外部的网络。服务器的CPU、内存、磁盘都正常,Web服务和数据库也没有异常,却在某些特定的网络路径上持续出现丢包或者异常的延迟,这时再考虑线路优化,或者调整网络方案,才有依据。
如果需要联系恒讯科技的技术支持,建议先把证据整理好:出现问题的时间段,受影响的地区和运营商,mtr的结果,curl分阶段的耗时,以及服务器资源的监控截图。带着这些信息去咨询,沟通会高效得多,问题也更容易定位。
香港云主机Ping值正常,为什么网站仍然慢?Ping只能说明基础的网络连通和往返延迟,反映不了服务器处理请求的速度、数据库的响应,或者页面资源的大小。用curl分阶段测试,看connect和ttfb,才能知道慢在哪里。
带宽升级后访问速度一定会提升吗?不一定。只有当带宽确实是瓶颈,也就是曲线长期贴着上限的时候,升级才有效果。如果慢是因为数据库、磁盘或者页面太大,加带宽不会有明显改善。
网站慢该优先升级CPU还是内存?先看监控数据再决定。CPU长期居高,就考虑CPU;频繁换页或者出现内存不足,就先升内存;如果瓶颈是磁盘I/O,升CPU和内存都帮不上。
CDN能解决所有访问慢的问题吗?不能。CDN对静态资源的加速效果明显,但动态内容、数据库查询,以及源站本身响应慢的问题,仍然需要在源站解决。
怎样判断是否需要更换线路?当服务器内部一切正常,问题稳定地出现在特定的地区或运营商,并且mtr显示路径上存在持续的丢包或异常延迟,这时再考虑更换线路或调整网络方案。没有这些证据就换线路,多半白费功夫。
排查的顺序
第一步,分类:是连接服务器慢,还是网站响应慢。
第二步,定位:网络、资源、Web服务、页面,每次只查一个方向,用数据说话。
第三步,才是动手:优化配置、升级资源,或者调整线路。
Copyright © 2013-2020. All Rights Reserved. 恒讯科技 深圳市恒讯科技有限公司 粤ICP备20052954号 IDC证:B1-20230800.移动站


