HTTP请求的访问路径

如下图,整个访问经过了以下的关键过程

image-20241005222633289

  • 客户端即浏览器初始化过程
  • 网络连接,包括DNS查询、TCP握手、TLS握手等
  • HTTP请求,这里会根据请求内容以及负端部署情况决策到请求的是静态内容还是动态内容,这个请求路径会有所不同
  • 静态内容请求经过网络到缓存节点(Web Caching)
  • 动态内容会直接访问到云端(或者服务端,The Cloud),过程中会经过网络防火墙、负载均衡最终请求会被转发到应用(Application)
  • 在应用的内部有web容器、业务逻辑,这里会对用户请求进行解析和处理,可能需要经过数据库查询、缓存查询和更新、请求其他服务接口、提交在线或者离线处理任务等等,根据不同的请求可能经过的服务和路径是不同的,最终都是会组装响应内容进行返回

问题响应和处理流程

1、在接受到这个问题的时候,首先需要确认几个问题:

  • 具体的页面地址是什么?或者域名是什么?这个是为了明确问题是站点是什么
  • 用户测试时的位置?这个包括地理位置,网络运营商,可以通过一些网站如https://ip138.com/ 来获取用户基本信息
  • 有没有尝试测试其他网站,访问速度是否正常?这个是为了做对比测试

2、需要快速查看网站访问监控,当前的响应rt,qps统计等关键业务指标是否正常。这个是为了快速确定方向,如果监控抖动,那大概率就是我们的服务出现了异常,如果在第一遍快速排查中一切正常,那至少我们可以知道这不是一个大面积的问题

3、为了能够确定服务情况,我们可以借助本地测试,还有听云等拨测工具,进行全范围的拨测,来确认我们的服务端接口是否正常。 在此期间,我们需要将cdn访问监控,页面加载过程中依赖的接口监控都巡查一边,这个就需要平时工作中能对业务依赖梳理清楚,对各个依赖做好监控。接入了cdn,监控最好细粒度到省份加运营商。

以下我们从服务端及客户端两个路径进行排查

客户端

1、客户端本身硬件问题,如CPU消耗过多,内存不足,电源节能模式下降频,都可能让当前客户端主机运行较慢。当然这个点也是我们在引导用户访问其他网页,检测是否有问题来做一些佐证,因为我们要向用户解释为什么访问其他公司的页面都好着呢,一访问你们的的就不行?

2、客户端浏览器的下载和渲染过程,这个需要从浏览器的调试模式中去观测和采集具体是哪些资源下载慢,或者加载出现问题,或者哪些接口数据加载慢等。

3、客户端到服务器的网络问题,这个可以通过 ping 进行检测,核心来看链路访问是否丢包。在用户带宽不足,或者所处的网络环境不佳的情况下等弱网环境下,确实会出现到一些特定的网站访问比较慢的情况

4、继续分析访问慢的原因,这个根据访问链路的过程来逐层剖析,HTTP请求的访问过程可以参考我前边的文章。第一个点就是DNS解析慢,DNS解析慢这个一般不会是本地的DNS层有问题,因为这个是公共服务,有问题的话,应该是用户访问所有页面可能都有问题,如果是访问特定域名下的页面慢,在DNS解析层面大概率是访问域名的权威DNS解析问题。比如权威DNS对某些特定查询不响应等等

5、DNS解析过后就到了TCP连接,如果客户端网络不佳,TCP连接可能会失败,或者在DNS解析出来的IP地址,不是最优的,或者客户端使用了VPN或者配置了访问代理,都可能让客户端访问到一个不应该访问到节点,比如有人配置了代理,访问到国外的接入点,所以如果用户能够有能力配合做类似curl的测试,拿到访问到的IP地址,那对于此类问题,可以迅速定位和解决

TCP本身对于应对弱网环境的能力不佳,在用户网络不佳的情况下,推荐对于服务端的接入点支持http3(quic)

6、用户网络与服务端接入点太远,这个就属于硬伤了,对于服务端的页面来讲,就需要借助CDN等技术来加速我们内容和接口

7、HTTP请求过程,客户端可能会碰上http劫持,或者http代理,出口防火墙等等可能会对出站的http请求做过滤规则,那这个过程中,也可能造成访问延迟,这个是需要先同问题用户沟通确认,一般普通用户很少会有这种情况,对于企业内的网络环境,就可能需要沟通确认下

8、在客户端访问协议,浏览器中如果http协议使用的http1.1,那如果页面同时引用和加载的资源(css,图片,js等)过多的话,浏览器无法进行并发下载,那势必有些资源是需要排队等待的。这个需要服务端支持http2,这样对于同时加载大量资源的页面打开会比较友好

9、内容大小与缓存,比较大的资源下载耗时本身就会很高,如果每次打开页面都需要进行实时下载,那这个速度就不大可能会好,那可以考虑对资源进行压缩,对于不变的静态资源,甚至API接口访问内容如果不需要实时变化的,都可以加上缓存,包括浏览器缓存和服务端缓存

10、CSS和JS优化:对于页面渲染部分非关键的js文件可以采用异步加载的方式,CSS也可以通过内联关键CSS,以更快的呈现折叠内容。JS与CSS本身也需要进行精简和压缩,降低js/css文件的大小

11、如果页面加载的图片、视频资源的话,也要考虑对于图片视频的压缩,比如使用更高压缩比的图片和视频的编码格式等等

服务端

判断标准

  • 服务端监控异常,包括cdn,服务端接口,服务端依赖资源等监控
  • 听云等拨测工具结果,判断是否访问接口存在超时或者延迟较高的情况,或者是否存在地域、运营商等特征聚集

可能的问题与处理方案

1、服务端入口带宽是否超限,ping是否有丢包,网络入口是否有流量突发?这里需要判断是否有ddos攻击,入口IP地址是否存在被防火墙引流清洗

2、静态内容是否使用CDN加速、源站的服务端缓存等等,动态接口针对于业务场景,对能缓存的内容也尽可能增加缓存,如Redis或者Memcached对接口返回内容做缓存,减少频繁的数据库或者第三方接口调用来获取返回内容

3、对于接入了cdn,那么用户的接入点会分散到各个地区。那需要确认用户大致的位置,网络运营商类型,用户出口ip,可以通过访问一些IP查询的网站获取,如果用户可以通过浏览器调试模式获取到具体的错误信息,会更容易排查。测试和排查cdn节点访问是否正常,ping延迟是否正常,cdn访问到的IP地址是否是最优的节点

4、服务端访问入口的负载均衡、防火墙等等接入层代理设备本身的负载、网络带宽、转发能力、响应延迟等,比如常用的Nginx来做七层负载均衡,入口负载均衡设备的cpu,网卡流量是否在正常水位线以内,这两个超限之后会拉慢响应速度

5、服务接口响应速度确认,在负载均衡上,如nginx的请求日志中,可以通过request_time upstream_response_time 的时间来大概判断是后端服务响应太慢,还是nginx到客户端之间的网络传输太慢,也可以判断在负载均衡上向服务转发请求过程中是否存在失败重试的情况

如果我们可以获取到用户的出口IP,可以更方便的从访问日志中查询到具体的访问日志,就可以更加精准的定位到具体是哪个方向的延迟增大

6、应用服务的响应慢,一般cpu负载,连接数,应用本身的处理能力(依赖应用日常的性能评估,性能压测等),内存,服务所在的节点带宽是否充足,比如现在的云主机、POD本身的内网带宽也是有上限的

7、对于有数据读写的情况下,磁盘的读写能力是否充足,需要监测服务节点的磁盘带宽、iops是否充足。对于有外部依赖的,如对接,第三方接口,数据库,缓存等,任何一个依赖慢了,或者失败了需要多次重试的,都可能会慢

8、数据库延迟,或者慢查询,动态接口查询数据库过程中,如果碰上大表,或者SQL问题,没有索引等都会让数据库成为访问过程中的瓶颈。我们需要能够对数据库性能进行监控,及时发现问题点;优化上基本的调优手段包括读写分离、多从库的负载均衡、分库分表等;访问的连接池优化,避免频繁打开和关闭数据库连接;数据库表索引优化,SQL优化等

9、数据库及其他依赖服务的响应延迟监测,与排查。一个服务端的接口,简单的可能查一下数据库就可以返回,复杂的接口,可能内部还需要调用其他服务接口来继续后续的业务逻辑,那这个过程中,需要对每个环节的输入输出RT进行上报和监控,以定位每个环节是否有性能瓶颈,响应延迟

10、服务端应用节点以及依赖的各个服务,做好容量监控,保证每个节点的工作负载稳定可控

11、内部调用中对于本身处理时间较多的接口,需要从同步调用转为异步调用,降低用户端的接口等待时间,减少同步阻塞

12、减少服务端不必要的API请求,内部调用从http转为RPC,可以获得更快更高效的API调用