Note: 因为头条的文章发表30天后不能修改. 所以文章后续的订正我会同步到 Github Pages 上, Github Pages 的地址见文末.
"网页加载慢该怎么排查", 这道题应该算作是经典面试题 "在浏览器地址栏输入一个URL后回车会发生什么?"的变种. 为了详细的回答这个问题, 我打算写一个系列详细的梳理这些知识. 今天只是做一个概述.
下图(点击查看大图)生动的展现了 HTTP 从客户端请求到响应完成的链路, 黑体加粗的字代表了不同的分析维度.
从 Client (用户端) 分析
- 硬件配置低. 比如用户设备的 CPU 或内存配置低.
- 资源不足. CPU 或者内存资源不足, 比如用户是否使用了 Chrome 这种 "吃内存大户" 的浏览器并且打开了很多网页?
从前端 Rendering (浏览器渲染过程) 分析
结合浏览器的 devtools 面板进行分析. (浏览器的 devtools 非常强大, 后期会有教程专门分析)
- 浏览器页面渲染的过程中存在异常. 这些异常有可能是网站的 JS 代码有 bug, 也有可能是浏览器上安装的插件有问题. 表征是 devtools 下的 console 面板在网页加载的过程中出现很多 Error 或 Warning 日志.
- 调用耗时过长的接口或请求的资源过多. 通过 devtools Network 的 Time 可以查看接口耗时.
- 页面的渲染性能不佳. 使用 devtools Performance 进行性能分析.
从 Networking (网络) 分析
- 用户端的带宽不足或所处环境网络不佳. 比如用户用的光纤, WIFI 还是流量, 是否处于地下室等弱网环境等.
- DNS 解析慢. DNS解析包括往复解析的次数及每次解析所花费的时间它们两者的积即是DNS解析所耗费的总时间, 在http请求的过程中, 域名解析和建立连接占的时间很多. 可以使用 ping 命令 ping 该域名, 如果解析记录返回的非常缓慢, 可以判断是 DNS 的问题.
- HTTP 劫持. 如果网站使用的是 HTTP 服务并且网站出现了垃圾广告等情况, 这说明可能出现了 HTTP 劫持.
- 未设置 CDN. 如果没有设置 CDN, 在跨线路访问(比如用户是铁通, 但是服务器部署在联通, 这种情况就是跨线路), 地理位置相差很远 等情况, 就容易发生网页打开缓慢. 排查方法还是使用 ping 命令, 当存在丢包或者很高延迟时(国内 ping 延迟超过 50 ms), 就会导致线路访问异常.
从 Services (服务端) 分析
对服务端进行分析的前提是, 已经确定是服务端接口耗时引起的 "网页打开慢", 所以我们通过提升服务器的响应速度, 来改善用户体验.
- Application 应用代码本身. 第一步应该分析相关的代码,找出相应的瓶颈,再来考虑具体的优化策略。
- 有一些性能问题,完全是由于代码写的不合理,通过直接修改一下代码就能解决问题的,比如for循环次数过多、作了很多无谓的条件判断、相同逻辑重复多次等。
- 其实可以考虑使用多线程或者异步代替原来的同步阻塞代码, 提升并发度.
- Database 数据库. 数据库的优化分 3 部分:
- SQL 调优, 由自带的慢查询日志或者开源的慢查询系统定位到具体的出问题的SQL.
- 架构层面的调优, 这一类调优包括读写分离、多从库负载均衡、水平和垂直分库分表等方面.
- 连接池调优. 随着业务访问量或者数据量的增长,原有的连接池参数可能不能很好地满足需求,这个时候就需要结合当前使用连接池的原理、具体的连接池监控数据和当前的业务量作一个综合的判断,通过反复的几次调试得到最终的调优参数。
- Web Cache 缓存. 什么情况适合使用缓存? 短时间内相同数据重复查询多次且数据更新不频繁的数据或者图片等静态资源.
- Load Balancer 负载均衡. 如果感觉单机优化后还是遇到了性能瓶颈, 这时候就适合使用 Nginx 做反向代理, 通过增加服务器这样就可以提高服务端的能力.
- Distrbuted Systems 分布式服务. 分布式服务涉及的知识非常多, 如服务的注册发现, RPC、心跳等网络通信调用的机制等, 最好使用成熟的开源框架. (以后的专题中会详细介绍)