网络异常测试
在这几年的微服务开发过程中遇到过两次因为网络问题导致的系统故障,并且没有做好降级策略,导致系统的不可用时间增加,所以今天专门整理一篇关于网络故障的问题分析处理以及开发中需要注意的地方。
基础部分
TCP 连接,先抛大图:
主要分为三部分:
- 建立连接
- 传输数据
- 关闭连接
原理不做过多介绍,主要说说常见的异常和模拟方式。
常见的异常类型
上面的异常是一些常见的功能性异常,其它性能方面的异常不在本文讨论范围。
实施手段
需要的工具
- python 脚本
- iptables,对网络流量进行规则过滤
- tcpkill,用来断开网络构造异常
- curl,发起 http 访问请求
Python脚本
主要作用是启动一个TCP监听,然后将接收到的数据在转发回去。
1 | #! /usr/bin/python |
iptables 基本使用
1 | // 查看当前生效规则 |
tcpkill 基本使用
https://yq.aliyun.com/articles/59308
1 | // 安装 |
curl 超时设置
使用 curl 有两个超时时间,一个是连接超时时间,另一个是数据传输的最大允许时间。
连接超时时间用 --connect-timeout
参数来指定,数据传输的最大允许时间用 -m
参数来指定。
1 | curl --connect-timeout 10 -m 20 "http://192.168.1.110:12345" |
实施过程
- A机器启动Python脚本,监听12345端口。
- B级器通过curl命令进行访问。
- 在访问过程中通过配置iptables来实现网络的各种异常情况。
- 通过 tcpkill 来实现连接中断的异常情况。
正常访问
1 | xyz@xyz-pc:~$ curl "http://192.168.1.110:12345" |
查看和清除规则
1 | xyz@xyz-pc:~$ sudo iptables -L -n |
连接超时
1 | xyz@xyz-pc:~$ sudo iptables -A OUTPUT -p tcp --syn --dport 12345 -j DROP |
读取数据超时
1 | xyz@xyz-pc:~$ sudo iptables -A OUTPUT -p tcp -m state --state ESTABLISHED --dport 12345 -j DROP |
拒绝连接
1 | xyz@xyz-pc:~$ sudo iptables -A OUTPUT -p tcp --dport 12345 -j REJECT |
连接被重置
这里需要将Python脚本的 client.close()
注释掉。
1 | xyz@xyz-pc:~$ sudo tcpkill -iwlp8s0 port 12345 |
总结
在越来越多的企业微服务化进程中,肯定会遇到网络请求的各种问题,当我们在做一个基础组件或者进行网络通信请求时需要考虑到这些异常情况,最好还是将各种常见的情况模拟实施一下,来保证服务的稳定性。首先要说的是请求的超时设置,不论是在进行 HTTP 访问还是封装后的 RPC 请求,超时设置是最基本的。
基于不同语言的不同组件实现质量来说。曾经遇到过一个问题是,一个服务处于假死状态,Java 的客户端中默认超时和多线程可以使主线程服务不会受到过多影响,golang 中的客户端默认设置了一个很长的超时时间,服务在一定程度上受到了影响,而Python的客户端超时时间也是很长,还有就是Python只有一个主线程再跑,所以此时服务会被 hang 住了。
所以这里还有一个问题就是服务降级,当前服务如果出现问题,重试几次后仍然失败,那么是否降级来保证当前服务的可用性,其实考虑的是异常服务对于当下的重要性,是否在整个核心服务链路当中,否则的话进行降级处理。
还有一个关键点是慎用重试,偶然的网络波动导致的异常在重试下会很有效,但是当遇到服务性能导致的超时问题时,就遇到大量的客户端重试导致请求翻倍,很可能会直接把服务打挂,所以不要轻易使用重试,可以通过一些额外的补偿机制来提高服务稳定性。
ad.
未防止爬虫盗爬我的文章,在末尾打个广告。这篇文章首发在我的个人博客 知一的指纹 http://noogel.xyz ,有需要技术交流的朋友可以加我个人微信:zhi2012666
参考
https://blog.csdn.net/llianlianpay/article/details/79768890
https://www.cnblogs.com/gl1573/p/10129382.html
https://blog.csdn.net/wangyiyungw/article/details/85004905