作者介绍:
胥峰
盛大游戏高级研究员 高级信息系统项目管理师
《Linux运维最佳实践》(在版)作者2006年毕业于南京大学,2011年加入盛大游戏。十年运维经验,曾参与盛大游戏多款大型端游和手游的上线运维,主导统一运维平台的产品功能设计和实施。拥有工信部认证高级信息系统项目管理师资格。
引言:在游戏运维过程中,我们经常会遇到各种看起来与网络有关的故障。如何快速定位和排除故障,是我们需要面对的挑战。
本文主要分享一些使用网络分析技术tcpdump来解决实际问题的案例,传递网络分析的思想、最佳实践,和大家一起探讨学习。
分享的内容由五部分组成:
1. 背景
2. 案例
3. 技巧
4. 原理
5. 总结
一、背景
游戏运维中精彩遇到这些问题:
- 游戏补丁更新失败有没有?
- 手游卡顿有没有?
- 玩家无法登录游戏有没有?
- … …
遇到这些问题,怎么办?
- “推说”玩家网络问题?
- 交给开发商?
- 我不知道?
- … …
其实,我们可以多做一步:先用常见网络分析技术如tcpdump,判断下问题,然后再决定下一步行动。
二、常见案例
说明:如下案例都通过tcpdump抓包并用Wireshark进行分析。关于这两个利器的使用技巧详见后文。
1. 客户端更新失败的分析解决
现象:2012年11月1日~11月7日某游戏技术封测,部分玩家更新失败
从这个图里,我们可以看到,玩家下载更新时,被引导到一个非我司的IP地址上。下面我们来看看,在底层的网络层面,发生了什么。
通过上述网络抓包,可以更清晰地看到来龙去脉,并可作为证据留存。
2. 虚拟机带宽形态异常的分析解决
在本例中,带宽最小值和最大值都是100Mb/s,这明显是有问题的。
我们抓包看看情况。
由图可见,在TCP的SYN包中,被携带了数据。这说明,该主机对外DOS攻击(原因是什么?各种啊。。)。
在目前的TCP协议实现中,SYN包中并不携带数据
注意: 有兴趣的同学可以关注下TCP Fast Open技术,在最新的内核中已经支持。这个技术允许在TCP SYN包中携带数据,以减少对端连续建立多个TCP通道的消耗。
3. Nginx 499 异常的分析解决
有你,是盛大推出的一款网络短信工具,有类似“朋友圈”的功能。
问题现象:在“有你”这款工具的运营中,发现Nginx日志中存在499状态码的访问,且较多。
499状态码为Nginx特有,意思是“客户端已经关闭连接”
通过分析,我们发现存在2个问题:
1)红色圈中的2个packet,可以看出从NetScaler收到syn包到转发给后端web时间delay达54秒。
2) 黄色圈中的3个packet,可以看出客户端在发了HTTP Request的0.6秒后,立即发送了一个[FIN,ACK]的包。
因此,也可以进行下一步排查了。
4. 手游用户访问异常的分析解决
这是该情况下的网络抓包截图。
通过对游戏的网络行为分析,总结如下3点:
1)中国移动对HTTP协议有串联设备分析请求与响应,可能过滤了我们的请求。(后续工作:可以向中国移动某分公司投诉)
2)游戏客户端发送的请求有需要优化的地方:User-Agent头部可以考虑完善补充(构造),对于HTTP协议来说,User-Agent在rfc2616(HTTP标准)中用的是SHOULD(即建议),但是事实上必须的。以下是某款知名手游的HTTP头部截图
3)游戏客户端发送的请求有需要优化的地方:POST请求把所有数据都放在了http header里面,导致post内容本身字段长度为0。这个使得“看起来不是那么正常”。建议尝试优化。
三、技巧大放送
1. Wireshark配置技巧
1)禁用解析
2)使用绝对序列号
3)自定义HTTP端口号
有时,我们的HTTP应用(以手游为多见)并不是开放在80的知名端口,而是使用了例如10001这样的高端口。为了使Wireshark能够主动以HTTP协议解析这些非知名端口的通信内容,我们需要自定义HTTP解析的端口。
4)使用追踪数据流功能
5)一招制敌:使用过滤器找出可能有问题的网络行为
tcp.analysis.retransmission or
tcp.analysis.fast_retransmission or
tcp.flags.reset == 1 or
icmp
2. tcpdump参数使用技巧
初次使用tcpdump时,使用tcpdump -h命令可以看到它有数十个参数。
根据我们在运维工作中的经验,掌握tcpdump以下5个参数即可满足大部分的工作需要了。
- -i参数。使用-i参数指定需要抓包的网卡。如果未指定的话,tcpdump会根据搜索到的系统中状态为UP的最小数字的网卡确定,一般情况下是eth0。使用-i参数通过指定需要抓包的网卡,可以有效的减少抓取到的数据包的数量,增加抓包的针对性,便于后续的分析工作。
- -nnn参数。使用-nnn参数禁用tcpdump展示时把IP、端口等转换为域名、端口对应的知名服务名称。这样看起来更加清晰。
- -s参数。使用-s参数,指定抓包的包大小。使用-s 0指定数据包大小为262144字节,可以使得抓到的数据包不被截断,完整反映数据包的内容。
- -c参数。使用-c参数,指定抓包的数量。
- -w参数。使用-w参数指定抓包文件保存到文件,以便后续使用Wireshark等工具进行分析。
3. tcpdump过滤器使用技巧
tcpdump提供了丰富的过滤器,以支持抓包时的精细化控制,达到减少无效信息干扰的效果。我们常用的过滤器规则有下面几个:
- host a.b.c.d:指定仅抓取本机和某主机a.b.c.d的数据通信。
- tcp port x:指定仅抓取TCP协议目的端口或者源端口为x的数据通信。
- icmp:指定仅抓取ICMP协议的数据通信。
- !:反向匹配,例如port ! 22,抓取非22端口的数据通信。
以上几种过滤器规则,可以使用and或者or进行组合,例如:
host a.b.c.d and tcp port x
则只抓取本机和某主机a.b.c.d之间基于TCP的目的端口或者源端口为x的数据通信。
tcp port x or icmp
则抓取TCP协议目的端口或者源端口为x的数据通信或者ICMP协议的数据通信。
4. tcpdump在安卓的使用方法
随着移动应用的增加,移动设备访问系统应用的情况越来越多,我们经常会遇到有用户抱怨说使用移动设备访问网站等业务慢的问题。在这种情况下,如果能够同时在移动设备和服务器上同时抓包,那么对于分析问题将会有很大的帮助。
注意:在Android系统抓包时,需要root权限,不同型号手机的root过程不同,在此不再进行赘述。
Android版本的tcpdump下载地址是:
http://www.androidtcpdump.com/android-tcpdump/downloads
另外,在Android系统抓包时,需要使用adb这个工具,下载地址是
http://developer.android.com
我们把下载后的tcpdump和adb工具及其依赖的dll放在c:\adb目录下
四、相关原理及解读
1. tcpdump程序调用模型
我们先回顾下一般网络程序的调用图。
再看一下tcpdump程序调用模型。
可见,tcpdump这一类的应用程序完全不同,它依赖的是libpcap。
libpcap使用的是一种称为设备层的包接口(packet interface on device level)技术。
使用这种技术,应用程序可以直接读写内核驱动层面的数据,而不经过完整的Linux网络协议栈。
在C语言中,调用设备层的包接口使用如下的方法:
#include <sys/socket.h> #include <netpacket/packet.h> #include <net/ethernet.h> /* the L2 protocols */ packet_socket = socket(PF_PACKET, int socket_type, int protocol);
PF_PACKET套接口:被用于接收和发送在设备驱动层(OSI Layer 2)的数据包。
在以上的函数调用中,socket_type可以是:
- SOCK_RAW,此时收发的数据包包括链路层头部,例如源MAC和目的MAC地址等。
- SOCK_DGRAM,此时收发的数据包不包括链路层头部,直接操作IP层头部和数据。
protocol:是指IEEE 802.3协议号。
特别的,如果是htons(ETH_P_ALL)则所有协议的数据包都被接收。
2. tcpdump与iptables的关系
可能会有疑问,如果一种输入的网络通信(INPUT)被iptables给禁止了,那么tcpdump还可以抓取到吗?
答案是肯定的。
- tcpdump直接从网络驱动层面抓取输入的数据,不经过任何Linux网络协议栈。
- iptables依赖的netfilter模块,工作在Linux网络协议栈中
因此:
- iptables对入栈的策略不会影响到tcpdump抓取。
- 但iptables的出栈策略会影响数据包发送到网络驱动层面,因此,它的出栈策略会影响到tcpdump的抓取。
tcpdump和iptables的关系,总结下来就是:
- tcpdump可以抓取到被iptables在INPUT链上DROP掉的数据包。
- tcpdump不能抓取到被iptables在OUTPUT链上DROP掉的数据包。
五、总结
在遇到网络问题时,记得使用tcpdump抓包看看,肯定有不一样的收获!
更多内容,请关注本人即将出版的《Linux运维最佳实践》一书。
对网络分析技术有兴趣的同学,可以加“运维技术实践”公众,或我个人微信号(xufengnju)一起探讨。
好消息!
据说,本文作者@胥峰同学将携新作《Linux运维最佳实践》,亲临GOPS2016全球运维大会·上海站,并做精彩演讲。
约么?