zoukankan      html  css  js  c++  java
  • 网络编程-为什么需要应用层做心跳处理?

    背景

    许多小伙伴做网络编程时,会自然而然的去做应用层的心跳检测机制,如果问为什么要做心跳检测,大部分人会说保活,及时发现连接失效等等。这篇文章会结合TCP协议原理来分析,使用应用层做心跳检测的原因和必要性。

    没有应用层心跳检测时

    在没有应用层心跳检测时,我们如何发现对端应用程序崩溃/对端主机崩溃/主机不可达等等异常呢?

    假如网络正常
    我们考虑异常时在发送数据包:
    • 如果对端程序崩溃还未重启,会发送FIN,本端可以立即感知
    • 如果对端 程序崩溃/主机崩溃 后已经重启,会发送RST,本端可以立即感知
    • 对端主机崩溃一直未重启,我们发送的数据包将会TCP超时
    • 对端主机不可达,我们发送的数据包将会TCP超时

    TCP超时重传的默认机制是什么呢?

    首先明确,超时重传的原理是在发送某一个数据以后就开启一个计时器,在一定时间内如果没有得到发送的数据报的ACK报文,那么就重新发送数据,直到发送成功为止。

    关于超时重传的时间间隔和重传次数,下面这篇博客比较详细的讲解了这个知识点:TCP/IP重传超时--RTO

    总结一下博客中的内容

    1. RTO有一个最小值,不同内核中是写死的,博客中提到的内核版本是200ms,就算RTT是0.5ms也不行的,会用200ms来发送第二次发送的数据包。
    2. TCP内核中可以修改两个参数
    /proc/sys/net/ipv4/tcp_retries1 (integer; default: 3)
    TCP尝试了3次(tcp_retries1默认3)重传后,还没有收到ACK的话,则后续每次重传都需要network layer先更新路由。
    
    /proc/sys/net/ipv4/tcp_retries2 (integer; default: 15)
    TCP默认最多做15次重传。根据RTO(retransmission timeout)不同,最后一次重传间隔大概是13到30分钟左右。如果15次重传都做完了,TCP/IP就会告诉应用层说:“搞不定了,包怎么都传不过去!”
    

    如果没有应用层心跳检测,我们发送的数据包,最差需要依靠TCP超时来判断对端出现问题,这个超时时间是很长的,在现代的业务中几乎无法满足业务的需求。

    我们考虑只接收对端数据包的过程:
    • 如果对端程序崩溃,会发送FIN,本端可以立即感知
    • 对端主机崩溃
      • 如果关闭了Tcp的KeepAlive保活机制,那么没有任何感知;
      • 如果开启了TCP keep_alive,会通过保活机制,发送几个检测包,要么超时,要么得到RST
    • 对端主机不可达,和上面的主机崩溃同理

    如果没有应用层心跳检测,我们在不发送,只接受的情况下,最差需要依靠Keep Alive机制的超时或RST来判断对端出现问题,超时时间为:2小时+75秒* 9次。这个时间在默认参数设置下也是很长的。另外,这三个参数也可以修改的:

    net.ipv4.tcp_keepalive_time 对应2小时
    net.ipv4.tcp_keepalive_intvl 对应75秒
    net.ipv4.tcp_keepalve_probes 对应9次
    
    假如网络异常

    假如有网络异常,但是对方主机和程序都正常

    发送数据包时:

    • 通过本端TCP超时,发现网络异常

    接收数据包时:

    • 通过Keep_Alive机制来探测

    有应用层心跳检测时

    通过上面的分析可以得知,对于网络应用,无论是依赖TCP超时还是Keep Alive,在最差的情况下的超时时间都是不可接受的。所以我们需要在应用层做一个类似的心跳检测机制,保证可以在任何情况下都可以快速的检测出异常情况。

    那么是否可以只发一次,在规定时间内没收到回复就判定连接异常呢?考虑下面的两种情况:

    • 网络波动,但是对端主机和服务都正常
    • 对端主机正忙于处理其他事务,响应慢了一些

    对这两种情况来说,如果检测一次,发现超时就判定连接失效基本属于误伤,可以通过多发送几次心跳检测包来规避上面的误伤情况。

    并且还需要考虑,在多次发送的心跳包,需要带序号,对端回复时,也要保证使用这个序号或者序号+1来匹配我们发出去的心跳包。如果编号对应不上,就不能算作此次检测成功了。

  • 相关阅读:
    Git入门
    基于sendmail的简单zabbix邮件报警
    zabbix agentd安装
    我整理的一份来自于线上的Nginx配置(Nginx.conf),希望对学习Nginx的有帮助
    【转载】Spring Boot引起的“堆外内存泄漏”排查及经验总结
    lodop+art-template实现web端漂亮的小票样式打印
    《阿里巴巴Java开发手册》改名《Java开发手册》,涵盖史无前例的三大升级
    Spring Boot的学习之路(02):和你一起阅读Spring Boot官网
    Spring Boot的学习之路(01):缘起
    『 效率工具 』Spring Boot版的轻量级代码生成器,减少70%以上的开发任务
  • 原文地址:https://www.cnblogs.com/ging/p/13467873.html
Copyright © 2011-2022 走看看