本文是通过学习倪朋飞老师的《Linux性能优化实战》 :网络请求延迟变大了,我该怎么办?

网络请求延迟变大了,我该怎么办?

  • 网络延迟
  • 案例准备
  • 总结

除了 DDoS 会带来网络延迟增大外,我想,你肯定见到过不少其他原因导致的网络延迟, 比如:

  • 网络传输慢,导致延迟;
  • Linux 内核协议栈报文处理慢,导致延迟;
  • 应用程序数据处理慢,导致延迟等等

网络延迟

提到网络延迟时,我们可能轻松想起它的含义——网络数据传输所用的时间。不过要注意,这个时间可能是单向的,指从源地址发送到目的地址的单程时间;也可能是双向的,即从源地址发送到目的地址,然后又从目的地址发回响应,这个往返全程所用的时间。

通常,我们更常用的是双向的往返通信延迟,比如 ping 测试的结果,就是往返延时 RTT(Round-Trip Time)。

除了网络延迟外,另一个常用的指标是应用程序延迟,它是指,从应用程序接收到请求, 再到发回响应,全程所用的时间。通常,应用程序延迟也指的是往返延迟,是网络数据传输时间加上数据处理时间的和。

我们可以用ping来测试网络延迟。ping 基于 ICMP 协议,它通过计算 ICMP 回显响应报文与 ICMP 回显请求报文的时间差,来获得往返延时。这个过程并不需要特殊认证,常被很多网络攻击利用,比如端口扫描工具 nmap、组包工具 hping3 等等。

所以,为了避免这些问题,很多网络服务会把 ICMP 禁止掉,这也就导致我们无法用 ping ,来测试网络服务的可用性和往返延时。这时,你可以用 traceroute 或 hping3 的 TCP 和 UDP 模式,来获取网络延迟。

比如,以 baidu.com 为例,可以执行下面的 hping3 命令,测试你的机器到百度搜索服务器的网络延迟:

# -c 表示发送 3 次请求,-S 表示设置 TCP SYN,-p 表示端口号为 80
hping3 -c 3 -S -p 80 baidu.com
HPING baidu.com (eth0 220.181.38.251): S set, 40 headers + 0 data bytes
len=46 ip=220.181.38.251 ttl=53 id=23532 sport=80 flags=SA seq=0 win=8192 rtt=4.9 ms
len=46 ip=220.181.38.251 ttl=53 id=27260 sport=80 flags=SA seq=1 win=8192 rtt=3.8 ms
len=46 ip=220.181.38.251 ttl=53 id=27170 sport=80 flags=SA seq=2 win=8192 rtt=5.8 ms--- baidu.com hping statistic ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 3.8/4.8/5.8 ms

从 hping3 的结果中,你可以看到,往返延迟 RTT 为 4.9 ms。

也可以用traceroute,得到类似结果:

# --tcp 表示使用 TCP 协议,-p 表示端口号,-n 表示不对结果中的 IP 地址执行反向域名解析
traceroute --tcp -p 80 -n baidu.com
traceroute to baidu.com (220.181.38.251), 30 hops max, 60 byte packets1  10.90.90.38  2.077 ms  2.121 ms  2.102 ms2  11.73.0.169  158.827 ms 11.73.0.161  6.230 ms 11.73.0.97  158.978 ms3  10.54.160.141  1.836 ms 10.54.160.217  1.927 ms 10.255.100.69  2.041 ms4  116.251.127.74  3.449 ms 116.251.127.82  3.531 ms 116.251.117.106  3.891 ms5  45.112.216.114  3.034 ms 10.102.34.193  2.599 ms 116.251.112.205  3.203 ms6  106.38.196.249  5.202 ms 106.38.196.29  5.740 ms 106.38.196.213  5.304 ms7  * 36.110.246.205  4.306 ms *8  * * *9  * * *
10  * * *
11  * * *
12  * * 220.181.38.251  4.832 ms

traceroute 会在路由的每一跳发送三个包,并在收到响应后,输出往返延时。如果无响应或者响应超时(默认 5s),就会输出一个星号。

案例准备

预先安装 docker、hping3、tcpdump、curl、wrk、Wireshark 等工具。

为了对比得出延迟增大的影响,首先,我们运行一个最简单的 html静态案例,在运行一个php应用程序案例。

接着,我们再用上面提到的 hping3 ,来测试它们的延迟,看看有什么区别。

# 测试 html静态案例 延迟
hping3 -c 3 -S -p 80 172.31.36.79
HPING 172.31.36.79 (eth0 172.31.36.79): S set, 40 headers + 0 data bytes
len=44 ip=172.31.36.79 ttl=64 DF id=0 sport=80 flags=SA seq=0 win=29200 rtt=1.9 ms
len=44 ip=172.31.36.79 ttl=64 DF id=0 sport=80 flags=SA seq=1 win=29200 rtt=0.8 ms
len=44 ip=172.31.36.79 ttl=64 DF id=0 sport=80 flags=SA seq=2 win=29200 rtt=0.6 ms--- 172.31.36.79 hping statistic ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.6/1.1/1.9 ms# 测试 php应用程序 延迟
HPING api.tickeup.com (eth0 172.31.36.79): S set, 40 headers + 0 data bytes
len=44 ip=172.31.36.79 ttl=64 DF id=0 sport=80 flags=SA seq=0 win=29200 rtt=1.9 ms
len=44 ip=172.31.36.79 ttl=64 DF id=0 sport=80 flags=SA seq=1 win=29200 rtt=1.8 ms
len=44 ip=172.31.36.79 ttl=64 DF id=0 sport=80 flags=SA seq=2 win=29200 rtt=1.6 ms--- api.tickeup.com hping statistic ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 1.6/1.8/1.9 ms

从这个输出你可以看到,两个的延迟差不多,都是 1.9ms。不过,这只是单个请求的情况。换成并发请求的话,又会怎么样呢?接下来,我们就用 wrk 试试。

执行下面的新命令,分别测试案例机器并发 100 时, 80 端口和 8080 端口的性能:

# 测试 html静态案例 性能
wrk --latency -c 1000 -t 2 --timeout 2 http://172.31.36.79/
Running 10s test @ http://172.31.36.79/2 threads and 1000 connectionsThread Stats   Avg      Stdev     Max   +/- StdevLatency    42.70ms  120.79ms   1.80s    93.59%Req/Sec    28.46k     1.24k   31.35k    66.00%Latency Distribution50%   12.62ms75%   17.05ms90%   44.67ms99%  669.70ms566398 requests in 10.03s, 247.91MB readSocket errors: connect 0, read 0, write 0, timeout 16
Requests/sec:  56474.03
Transfer/sec:     24.72MB
# 测试 php应用程序 性能
wrk --latency -c 1000 -t 2 --timeout 2 http://api.tickeup.com/
Running 10s test @ http://api.tickeup.com/2 threads and 1000 connectionsThread Stats   Avg      Stdev     Max   +/- StdevLatency   415.39ms  212.18ms   1.99s    68.96%Req/Sec     1.09k   792.57     4.02k    73.73%Latency Distribution50%  400.62ms75%  576.65ms90%  704.99ms99%    1.00s 17515 requests in 10.03s, 5.07MB readSocket errors: connect 0, read 0, write 0, timeout 341Non-2xx or 3xx responses: 17170
Requests/sec:   1746.08
Transfer/sec:    517.43KB

从上面两个输出可以看到, html静态案例 的平均延迟是 42.70ms,而php应用程序案例的平均延迟则是 415.39ms。从延迟的分布上来看,html静态案例 90% 的请求,都可以在 44.67ms 以内完成;php应用程序案例 50% 的请求,就已经达到 了 400.62 ms。

再结合上面 hping3 的输出,我们很容易发现,php应用程序案例 在并发请求下的延迟增大了很多,这是怎么回事呢?

我们使用tcpdump命令,抓取收发的网络包,分析网 络的收发过程有没有问题。然后存储为php.pcap,使用Wireshark进行分析:

# 测试 php应用程序 性能
wrk --latency -c 1000 -t 2 --timeout 2 http://api.tickeup.com/
# 使用tcpdump 抓包
tcpdump -nn tcp port 80 -w php.pcap

当 wrk 命令结束后,再次切换回终端一,并按下 Ctrl+C 结束 tcpdump 命令。然后,再 把抓取到的 php.pcap ,复制到装有 Wireshark 的机器中(如果 VM1 已经带有图形界 面,那么可以跳过复制步骤),并用 Wireshark 打开它。

由于网络包的数量比较多,我们可以先过滤一下。比如,在选择一个包后,你可以单击右 键并选择 “Follow” -> “TCP Stream”,如下图所示:

然后,关闭弹出来的对话框,回到 Wireshark 主窗口。这时候,你会发现 Wireshark 已经 自动帮你设置了一个过滤表达式 tcp.stream eq 24。如下图所示(图中省去了源和目的 IP 地址):

从这里,可以看到这个 TCP 连接从三次握手开始的每个请求和响应情况。当然,这可能 还不够直观,你可以继续点击菜单栏里的 Statistics -> Flow Graph,选中 “Limit to display filter” 并设置 Flow type 为 “TCP Flows”:

注意,这个图的左边是客户端,而右边是应用服务器。通过这个图就可以看出,前面三次握手,以及第一次 HTTP 请求和响应还是挺快的,但第二次 HTTP 请求就比较慢了,特别是客户端在收到服务器第一个分组后,40ms 后才发出了 ACK 响应(图中蓝色行)。

实际上,这是 TCP 延迟确认(Delayed ACK)的最小超时时间。那什么是延迟确认呢?这是针对 TCP ACK 的一种优化机制,也就是说,不用每次请 求都发送一个 ACK,而是先等一会儿(比如 40ms),看看有没有“顺风车”。如果这段 时间内,正好有其他包需要发送,那就捎带着 ACK 一起发送过去。当然,如果一直等不到 其他包,那就超时后单独发送 ACK。

总结

网络延迟,是最核心的网络性能指标。由于网络传输、网络包处理等各种因素的影响,网络延迟不可避免。但过大的网络延迟,会直接影响用户的体验。

所以,在发现网络延迟增大后,你可以用 traceroute、hping3、tcpdump、Wireshark、 strace 等多种工具,来定位网络中的潜在问题。比如:

  • 使用 hping3 以及 wrk 等工具,确认单次请求和并发请求情况的网络延迟是否正常。
  • 使用 traceroute,确认路由是否正确,并查看路由中每一跳网关的延迟。
  • 使用 tcpdump 和 Wireshark,确认网络包的收发是否正常。
  • 使用 strace 等,观察应用程序对网络套接字的调用情况是否正常。

这样,就可以依次从路由、网络包的收发、再到应用程序等,逐层排查,直到定位问题根源。

网络请求延迟变大了,我该怎么办?相关推荐

  1. 40 | 案例篇:网络请求延迟变大了,我该怎么办?

    上一节,学习了碰到分布式拒绝服务(DDoS)的缓解方法.简单回顾一下,DDoS 利用大量的伪造请求,导致目标服务要耗费大量资源,来处理这些无效请求,进而无法正常响应正常用户的请求. 由于 DDoS 的 ...

  2. linux【网络】网络请求延迟变大了,我该怎么办?

    文章目录 1. 回顾 2. 网络延迟 3. 案例准备 4. 总结 1. 回顾 DDoS 利用大量的伪造请求,导致目标服务要耗费大量资源,来处理这些无效请求,进而无法正常响应正常用户的请求. 由于 DD ...

  3. linux网卡通信延迟高,Linux性能优化-网络请求延迟变大

    目录 网络延迟 案例分析 总结 网络延迟 常用的是双向的往返通信延迟,比如 ping 测试的结果,就是往返延时 RTT(Round-Trip Time) 除了网络延迟外,另一个常用的指标是应用程序延迟 ...

  4. 一步步搭建Retrofit+RxJava+MVP网络请求框架(二),个人认为这次封装比较强大了

    在前面已经初步封装了一个MVP的网络请求框架,那只是个雏形,还有很多功能不完善,现在进一步进行封装.添加了网络请求时的等待框,retrofit中添加了日志打印拦截器,添加了token拦截器,并且对Da ...

  5. 一步步搭建Retrofit+RxJava+MVP网络请求框架(二),个人认为这次封装比较强大了...

    在前面已经初步封装了一个MVP的网络请求框架,那只是个雏形,还有很多功能不完善,现在进一步进行封装.添加了网络请求时的等待框,retrofit中添加了日志打印拦截器,添加了token拦截器,并且对Da ...

  6. android 设置允许http请求_网络请求框架----OkHttp原理

    一.前言 在 Android 中,网络请求是一个必不可少的功能,因此就有许多代表网络请求客户端的组件库,具有代表性的有下面三种: Apache 的 HTTP 客户端组件 HttpClient. Jav ...

  7. 网络请求与本地函数调用的区别

    本地函数调用是可预测的,并且成功或失败仅仅取决于控制的参数.网络请求是不可预测的,请求或者响应可能由于网络问题而丢失,或者远程计算机可能速度慢或不可用,这些问题完全不在控制范围之内.网络问题很常见,因 ...

  8. Flutter学习之事件循环机制、数据库、网络请求

    一.前言 学习了布局实例和交互后,算是对Flutter入门了,基本可以实现一些普通页面搭建和交互效果了.但是这远远还不够,现在App都是需要网络访问的,而今天的目标就是学习IO和网络这一块. 二.Da ...

  9. HTTPX: 青出于蓝,比肩requests的新生代网络请求库

    作为新生代的网络请求库,HTTPX 不仅支持 requests 的所有操作,同时支持 异步API 及 HTTP/2.根据官网的描述,总结有如下特点: 标准的同步接口及异步支持 HTTP/1.1 和 H ...

最新文章

  1. 淘宝API商家自用型应用程序全部源代码和详细的帮助文档(1元有偿提供)
  2. P3373 【模板】线段树 2
  3. [华为机试练习题]55.最大公约数 amp; 多个数的最大公约数
  4. java环境变量设置 成功_java环境变量设置
  5. 【OCR技术系列之八】端到端不定长文本识别CRNN代码实现
  6. 自己动手构造编译系统:编译、汇编与链接2.1.4 语义分析
  7. 如何开始ChickTech章节
  8. while循环random结合_Java 经典算法:二分法查找(循环和递归两种方式实现)
  9. linux sudo使用和sudoers配置详解
  10. mysql锁表和解锁语句
  11. okhttp配置缓存策略_一网打尽OkHttp中的缓存问题
  12. strictmode
  13. 企业库2.0培训系列课程大纲[意见征询]
  14. 谷歌浏览器:设置在新标签页中打开链接(不要同一个标签页覆盖打开标签页)
  15. linux 备份命令
  16. 微会动微营销引擎:SEM效果提升的2大方向+5种能力+7个策略
  17. JavsScript
  18. 使用Zend studio+WAMP来调试Wordpress后台的PHP程序的一些非常关键的信息(原创)
  19. DNS-named服务器配置
  20. [免费专栏] Android安全之Android Fragment注入

热门文章

  1. 员工和供应商,撑起了董明珠的手机梦
  2. 变异系数超出(0,1)范围
  3. NETAPP SAN存储知识
  4. TortoiseSVN下载安装及配置中文语言包
  5. 《前端图形学实战》几何学在前端边界计算中的应用和原理分析
  6. NeoVIM安装与配置(Windos 10)
  7. Serial ATA知识交流(一)——sata接口硬盘图解
  8. 10 款最好的 Python IDE
  9. python不同版本中浮点除法和整数除法
  10. 想做程序员,这些“潜台词”你能get几个?