当前位置: 首页 > 科技观察

有了这个Linux网络延迟排查方法,你再也不用加班啦~_0

时间:2023-03-18 17:45:09 科技观察

在Linux服务器中,可以通过内核调优、DPDK、XDP来提升服务器的抗攻击能力,减少DDoS对服务器的影响正常服务。影响。在应用中,可以使用各级缓存、WAF、CDN等来减轻DDoS对应用的影响。但是需要注意的是,如果DDoS流??量到达了Linux服务器,即使在应用层做了各种优化,网络服务延迟一般也会比平时大很多。所以在实际应用中,我们通常会使用带有专业流量清洗和网络防火墙设备的Linux服务器来缓解这个问题。除了DDoS导致的网络延迟增加,我想你一定见过很多其他原因导致的网络延迟,比如网络传输慢导致的延迟。由Linux内核堆栈中缓慢的数据包处理引起的延迟。应用数据处理慢等导致的延迟。那么遇到这些原因导致的延迟我们应该怎么办呢?如何定位网络延迟的根源?让我们在本文中讨论网络延迟。LinuxNetworkLatency说到网络延迟(NetworkLatency),人们通常认为是指网络数据传输所需要的时间。不过这里的“时间”指的是双向流量,即数据从源端发送到目的地,然后从目的地址返回响应的往返时间:RTT(Round-Trip时间)。除了网络延迟之外,另一个常用的指标是应用延迟(ApplicationLatency),它指的是一个应用从收到请求到返回响应所花费的时间。通常,应用程序延迟(也称为往返延迟)是网络数据传输时间加上数据处理时间的总和。通常人们使用ping命令来测试网络延迟。Ping基于ICMP协议。它通过计算ICMP发送的响应消息和ICMP发送的请求消息之间的时间差来获得往返延迟时间。这个过程不需要特殊的认证,所以经常被很多网络攻击所利用,比如端口扫描工具nmap,分组工具hping3等。所以很多网络服务为了避免这些问题,禁用了ICMP,使得无法使用ping来测试网络服务的可用性和往返延迟。在这种情况下,您可以使用traceroute或hping3的TCP和UDP模式来获取网络延迟。例如:#-c:3requests#-S:SetTCPSYN#-p:Setportto80$hping3-c3-S-p80google.comHPINGgoogle.com(eth0142.250.64.110):Sset,40个标头+0个数据字节len=46ip=142.250.64.110ttl=51id=47908sport=80flags=SAseq=0win=8192rtt=9.3mslen=46ip=142.250.64.110ttl=51id=6788sport=80flags=SAseq=1win=8192rtt=10.9mslen=46ip=142.250.64.110ttl=51id=37699sport=80flags=SAseq=2win=8192rtt=11.9ms---百度.comhpingstatistic---3packetstransmitted,3packetsreceived,0%packetlossround-tripmin/avg/max=9.3/10.9/11.9ms当然,你也可以使用traceroute:$traceroute--tcp-p80-ngoogle.com到google.com(142.250.190.110)的跟踪路由,最多30跳,60字节数据包1***2240.1.236.340.198ms**3**243.254.11.50.189ms4*240.1.236.170.216ms240.1.236.240.175毫秒5241.0.12.760.181毫秒108.166.244.150.234毫秒241.0.12.760.219毫秒...24142.250.190.11017.465毫秒108.1712毫秒184.2442.251.60.20718.595mstraceroute在路由的每一跳发送三个数据包,并在收到响应后输出往返延迟如果没有响应或响应超时(默认5s),将输出星号*。案例展示我们需要在这个演示中托管host1和host2两个主机:host1(192.168.0.30):托管两个Nginxweb应用程序(正常和延迟)host2(192.168.0.2):分析主机host1在host1上准备就绪,让我们运行并开始两个容器,官方Nginx和Nginx延迟版本:/nginx:latencyb99bd136dcfd907747d9c803fdc0255e578bad6d66f4e9c32b826d75b6812724运行以下命令以验证两个容器都在服务流量:$curlhttp://127.0.0.1...html>

感谢您使用nginx。

$curlhttp://127.0.0.1:8080...

感谢您使用nginx。

host2准备好了现在让我们使用上面提到的hping3来测试它们的延迟以查看差异。在host2中执行如下命令测试案例机8080端口和80端口的延迟:80端口:$hping3-c3-S-p80192.168.0.30HPING192.168.0.30(eth0192.168.0.30):Sset,40headers+0databyteslen=44ip=192.168.0.30ttl=64DFid=0sport=80flags=SAseq=0win=29200rtt=7.8mslen=44ip=192.168.0.30ttl=64DFid=0sport=80flags=SAseq=1win=29200rtt=7.7mslen=44ip=192.168.0.30ttl=64DFid=0sport=80flags=SAseq=2win=29200rtt=7.6ms---192.168.0.30hpingstatistic---发送了3个数据包,接收了3个数据包,0%丢包往返min/avg/max=7.6/7.7/7.8ms8080port:#testport8080delay$hping3-c3-S-p8080192.168.0.30HPING192.168.0.30(eth0192.168.0.30):Sset,40headers+0databyteslen=44ip=192.168.0.30ttl=64DFid=0sport=8080flags=SAseq=0win=29200rtt=7.7mslen=44ip=192.168.0.30ttl=64DFid=0sport=8080flags=SAseq=1win=29200rtt=7.6mslen=44ip=192.168.0.30ttl=64DFid=0sport=8080flags=SAseq=2win=29200rtt=7.3毫秒---192.168.0.30马力ingstatistic---传输了3个数据包,接收了3个数据包,0%数据包丢失往返min/avg/max=7.3/7.6/7.7ms从这个输出你可以看到两个端口有大约相同的延迟,都是7毫秒但这仅适用于单个请求。如果切换到并发请求怎么办?接下来,让我们用wrk(https://github.com/wg/wrk)试试看。80端口:$wrk--latency-c100-t2--timeout2http://192.168.0.30/Running10stest@http://192.168.0.30/2threadsand100connectionsThreadStatsAvgStdevMax+/-Stdev延迟9.19ms12.32ms319.61ms97.80%Req/Sec6.20k426.808.25k85.50%延迟分布50%7.78ms75%8.22ms90%9.14ms99%50.53ms/1.500请求1230580请求秒:12340.91传输/秒:10.00MB8080端口:$wrk--latency-c100-t2--timeout2http://192.168.0.30:8080/运行10s测试@http://192.168.0.30:8080/2个线程和100个连接线程统计平均StdevMax+/-Stdev延迟43.60ms6.41ms56.58ms97.06%Req/Sec1.15k120.291.92k88.50%延迟分布50%44.02ms75%44.33ms92%47.9610.01秒内22853毫秒请求,18.55MB读取请求/秒:2283.31TRansfer/sec:1.85MB从上面两个输出可以看出,官方Nginx(监听80端口)的平均延迟为9.19ms,而案例Nginx(监听8080端口)的平均延迟为43.6ms。从延迟分布来看,Nginx官方可以在9ms内完成90%的请求;以Nginx为例,50%的请求都达到了44ms。那么这是怎么回事?让我们做一些分析:在host1中,让我们使用tcpdump来捕获一些网络数据包:$tcpdump-nntcpport8080-wnginx.pcap现在,在host2上重新运行wrk命令$wrk--latency-c100-t2--timeout2http://192.168.0.30:8080/当wrk命令结束后,再次切换回Terminal1(host1的终端),按Ctrl+C结束tcpdump命令。然后,使用Wireshark将抓取的nginx.pcap复制到本机(如果VM1(host1的虚拟机)已经有图形界面,可以跳过复制步骤),使用Wireshark打开。由于网络数据包比较多,我们可以先过滤一下。例如,选中一个数据包后,可以右击选择“Follow”->“TCPStream”,如下图所示:然后,关闭弹出对话框,返回Wireshark主窗口。这时候你会发现Wireshark已经自动为你设置了一个过滤表达式tcp.streameq24。如下图(图中省略了源IP和目的IP):从这里可以看到这个TCP连接从三次握手开始的每一次请求和响应。当然,这样可能不够直观,可以继续点击菜单栏中的Statistics->FlowGraph,选择“Limittodisplayfilter”,将Flowtype设置为“TCPFlows”:请注意左侧图中最右边是客户端,右边是Nginx服务器。从这个图中可以看出,前三次握手和第一次HTTP请求和响应都相当快,但是第二次HTTP请求就比较慢了,尤其是客户端收到服务器发来的第一个数据包之后。ACK响应(图中的蓝线)在40毫秒后发送。看到40ms这个值,是不是想到了什么?实际上,这是TCP延迟ACK的最小超时时间。这是TCPACK的一种优化机制,即不是每次请求都发送ACK,而是等待一段时间(比如40ms),看是否有“搭车”的数据包。如果这段时间还有其他数据包要发送,它们将与ACK一起发送。当然,如果不能等待其他包,超时后会单独发送ACK。由于案例中的client有40ms的延迟,我们有理由怀疑client启用了延迟确认机制。这里的client其实就是之前运行的wrk。根据TCP文档,只有当TCP套接字专门设置为TCP_QUICKACK时才会启用快速确认模式(FastAcknowledgmentMode);否则,将默认使用延迟确认机制:TCP_QUICKACK(自Linux2.4.4起)如果设置则启用quickack模式,如果清除则禁用quickack模式。在quickack模式下,ack立即发送,而不是根据正常TCP操作在需要时延迟发送。这个标志不是永久性的,它只允许切换到quickack模式或从quickack模式切换。TCP协议的后续操作将再次进入/离开quickack模式,这取决于内部协议处理以及延迟确认超时发生和数据传输等因素。此选项不应在旨在可移植的代码中使用。让我们测试我们的查询:$strace-fwrk--latency-c100-t2--timeout2http://192.168.0.30:8080/...setsockopt(52,SOL_TCP,TCP_NODELAY,[1],4)=0...OK可见wrk只设置了TCP_NODELAY选项,并没有设置TCP_QUICKACK。现在你可以看到延迟Nginx(caseNginx)响应有延迟的原因了。结论在本文中,我们向您展示了如何分析增加的网络延迟。网络延迟是核心网络性能指标。由于网络传输、网络包处理等多种因素的影响,网络延迟是不可避免的。但是过多的网络延迟会直接影响用户体验。使用hping3、wrk等工具确认单个请求和并发请求的网络延迟是否正常。使用traceroute,确认路由正确,并查看路由上每个网关跃点的延迟。使用tcpdump和Wireshark确认正在发送和接收网络数据包。使用strace等观察应用程序对网络socket的调用是否正常。