之前说了 CPU、内存 、IO 在排查过程中可能出现的问题以及出现问题会影响的指标,这次就来看看在 linux 中网络的问题。

在实际中我们遇到的最多的网络问题就是:不通!!!无论是 ping 不通,物理链路不通,还是 dns 解析有问题导致的不通,还是容器间网络访问网络隔离造成的不通,等等,这个问题总是由于部署上的环境导致的。还有一类比较烦的问题就是网络带宽本来就不高的情况下,大量的请求导致网络的拥塞,最明显的感受就是接口请求超时,各种超时,nginx 超时,请求本身超时等等。对于这些问题如何进行排查呢?

诊断指标

sar

命令

sar -n DEV 1

1
2
3
4
5
6
7
8
9
10
[root@Linkin ~]# sar -n DEV 1
Linux 3.10.0-1062.9.1.el7.x86_64 (Linkin) 07/04/2020 _x86_64_ (2 CPU)

03:03:40 PM IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s
03:03:41 PM br-22dd849a79f5 0.00 0.00 0.00 0.00 0.00 0.00 0.00
03:03:41 PM br-dac186ab0c70 0.00 0.00 0.00 0.00 0.00 0.00 0.00
03:03:41 PM veth860c89a 0.00 0.00 0.00 0.00 0.00 0.00 0.00
03:03:41 PM eth0 5.00 4.00 0.30 2.43 0.00 0.00 0.00
03:03:41 PM lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00
03:03:41 PM docker0 0.00 0.00 0.00 0.00 0.00 0.00 0.00

指标

这个命令可以清楚的看到整体的网络吞吐情况

rxpck/s、 txpck/s 接收和发送的 PPS 包 / 秒

rxkB/s、txkB/s 接收和发送的吞吐量 KB/ 秒

iperf3

命令

用于测试网速、带宽

1
2
3
4
5
6
7
8
# -s 表示启动服务端,-i 表示汇报间隔,-p 表示监听端口
$ iperf3 -s -i 1 -p 10000

# -c 表示启动客户端,192.168.10.30 为目标服务器的 IP
# -b 表示目标带宽 (单位是 bits/s)
# -t 表示测试时间
# -P 表示并发数,-p 表示目标服务器监听端口
$ iperf3 -c 192.168.10.30 -b 1G -t 15 -P 2 -p 10000

nslookup & dig

命令

千万不要小看 DNS 的问题,很多时候 DNS 解析会出现很多问题,特别是有 DNS 缓存的时候

1
2
3
4
5
6
7
8
9
10
# 安装
yum install bind-utils

# 使用
nslookup www.baidu.com

# +trace 表示开启跟踪查询
# +nodnssec 表示禁止 DNS 安全扩展
dig +trace +nodnssec www.baidu.com
dig linkinstar.com @localhost

tcpdump

这个抓包工具可太强大了,命令参数也很多,举例常用的:

1
2
3
4
# -i eth0 指定网卡
# -nn host 10.0.2.1 主机过滤
# -nn tcp 协议过滤
# -nn dst port 80 端口过滤

内核参数修改提及

其实很多网络优化的参数都是可以通过修改 linux 内核参数进行调优

vi /etc/sysctl.conf

但是这里的调整可太讲究了,涉及的知识点太多,缓冲区最大值、队列长度等等,其实我的建议是,要不就直接不动,等到有问题再说,要不就直接交给有经验的运维搞定,直接复制网上的配置文件覆盖不太可取,万一出现问题不知道如何进行处理。

排查步骤

  1. 保证网络通,那肯定一上来最靠谱的就是 ping 了,网络要是都不通的话,那就没啥好说的了
  2. 查看网络请求情况,就是看,现在网络是否确实请求量很大,或者说请求数量很多,或者带宽资源不足等情况
  3. 查看网络资源状态,查看当前有多少连接数,各个 TCP\UDP 连接状态是否正常,很大程度上就能反映出问题

排查原因

其实网络导致的问题可以分为两种:

  1. 不通
  2. 卡了

但是导致这两种情况出现的原因纷繁复杂,太多无厘头的问题出现了,导致网络一直是 linux 里面的一座大山。

下面举例说几种现实中出现过的情况。

防火墙

几乎所有的人都会被这个玩意坑过一次,长记性之后又会被坑第二次。

第一次玩 linux 服务器的时候就被这个玩意坑了一天,所有东西查到最后,发现防火墙没关,或者端口没开放,导致无法访问。

第二次是云服务器坑了一波,服务器的防火墙是关了,但是云厂商有着自己的安全策略规则,你必须手动去网页上开放进行设置。

DNS 解析问题

这里分为两种,一种是外网的 DNS 解析,这种要不就是 DNS 服务器没配置,要不就是 DNS 解析服务器确实有问题。

一种是内网的 DNS 解析,因为内网里面也会使用 DNS 进行访问和请求,这个时候很多时候就会出现问题,一般就是 ping 不通,然后就用 dig 进行查。

还有就是前面的 LB 层,也就是如 NGINX 这样的负载均衡上缓存了 DNS 解析,当后面的 IP 更换导致负载出现问题。

大量 TIME_WAIT

出现原因是程序 bug,大量客户端请求后异常关闭,说 TCP 的时候这个状态之前说过,这里就不再详述了。

大量 SYN_RECV

可能由于 SYN FLOOD 攻击导致,那这个调内核参数可以缓解,但是如果真的是外网部署遇到这样的情况,如果出现频繁,优先考虑封 IP,云厂商的服务或者 CDN

容器间网络不通

虽然现在又 K8S 这样的容器编排,但在这之前容器间的网络总是有着各种问题,无论是使用 host 网络,还是网桥,总之网络不通服务无法访问,总是存在,这个时候抓包往往就成了最靠谱的解决方案。ping,然后直接抓 icmp 包,一个个抓过来,eth0,docker0,flannel0…

请求过多

其实很多时候,网络上的问题就是请求发过去相应时间过长了,导致用户感受就是卡,而卡在网络情况不好的时候反映尤为明显,需要注意的是,有的时候带宽资源占满,你可能连服务器都无法进行登录了。

这个时候你需要做的就是分析出现这样情况的原因,多数情况下都是由于最底层的数据查询有问题,导致 IO 瓶颈等,一般来说,优化数据库查询时间往往成为了解决问题的关键。其次就是缓存,这个往往马上就能瞬间提升性能。最后就是,要做好安全和限流工作,再怎么说服务器总是有瓶颈的,如果用户之间压你的服务,就是想把你带宽占满,如果没有做好合理的安全策略和限流工作,恐怕很快就凉了。

总结

网络就是制定了各种协议,将数据封装成各种样子,以便能稳定的在网络中传输。我们学习网络协议和原理的目的是为了在出现问题的时候尽快能定位到问题,避免问题的发生。

上学的时候,老师曾经就和我们说过,一个网络工程师去现场,就是原来是 ping 不通的,但是搞一搞,最后通了,工作就完成了。但看似简单的背后,其实藏着各种各样的复杂问题,端口,协议,dns其中的任何一个步骤都会导致问题。

所以在遇到网络问题的时候也不要慌张,一步步来,从头走到尾,总能发现最后的问题。