从TCP协议到TCP通信的各种异常现象
面客户端的错误码和报文情况我们可以知道,在kill进程时TCP协议是能够感知到的,并且发送的FIN报文。 我们再进一步的思考一下,为什么kill进程会有FIN呢?这个与前面crash的差异在哪?其实kill进程是通过shell想内核发送了SIGKILL或者SIGTERM,内核接收到该信号之后会进行相应的扫尾工作,因此可以看到服务端发送了FIN报文。 3. Server进程所在的主机关机 主机关机(这里指手动关机)的情况与进程被kill是类似的。这时因为在系统关闭时,init进程会给所有进程发送SIGTERM信号,等待一段时间(5~20秒),然后再给所有仍在运行的进程发送SIGKILL信号。当服务器进程死掉时,会关闭所有文件描述符。带来的影响和上面杀死server相同。 4. Server进程所在的主机宕机 这是我们线上另一种比较常见的状况。即使宕机是一个小概率事件,线上几千台服务器动不动一两台挂掉也是常有的事。这里挂掉其实包括2种情况,一种是内核panic,另外一种情况是出现了掉电。对于内核panic的情况不会像关机那样会预先杀死上面的进程,而是突然性的。那么此时我们的客户端准备给服务器端发送一个请求,它由write写入内核,由TCP作为一个报文发出,但因为主机已经挂掉,因此客户端无法收到ACK。于是客户端TCP持续重传分节,试图从服务器上接收一个ACK,然而服务器始终不能应答,重传数次之后,大约几分钟才停止,之后返回一个ETIMEDOUT错误。在这种情况下,如果我们调用的是同步发送接口,则在发送缓冲区慢的情况下会阻塞在这里,导致程序阻塞。 这个时间真的很长,对于某些应用这种长时间的卡顿是不能接受的。因此,需要一种手段处理这种情况,在套接字接口中可以通过SO_SNDTIMEO标记进行设置。但是有利也有弊,如果设置了该参数,可能会出现这的数据发送超时的情况,进而出现向服务端发送重复数据的情况,此时需要服务端做去重处理。 5. 服务器进程所在的主机宕机后重启 在客户端发出请求前,服务器端主机经历了宕机—重启的过程。当客户端TCP把分节发送到服务器端所在的主机,服务器端所在主机的TCP丢失了崩溃前所有连接信息,即TCP收到了一个根本不存在连接上(也就是我们前文介绍的查找不到socket数据结构)的报文,所以会响应一个RST分节。
至此,关于TCP协议中各种异常情况介绍完了,详细了解这些内容后对后续线上问题的分析和解决会有很大的帮助。当然,也有可能还有其它本 (编辑:开发网_开封站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |