V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
jdz
V2EX  ›  程序员

为什么分布式软件一般都使用心跳包而不适用 tcp 的保活机制呢

  •  
  •   jdz · 2020-03-31 17:49:04 +08:00 · 6690 次点击
    这是一个创建于 1690 天前的主题,其中的信息可能已经有所发展或是发生改变。
    39 条回复    2020-04-02 18:23:06 +08:00
    guyeu
        1
    guyeu  
       2020-03-31 18:31:52 +08:00   ❤️ 14
    1. 默认配置和分布式服务的需求差异比较大;
    2. 调优难,往往需要修改操作系统参数,而这会影响一堆服务;
    3. 扩展难度大,比如很多分布式服务的心跳包会带数据;
    4. 只能检测连接的活性,而无法检测服务的可用性;
    5. 处理事件不方便,很多语言的标准库提供的 API 很难用;
    6. 没有收益,TCP 自带的保活相比应用层自己实现,没有效率优势;
    123444a
        2
    123444a  
       2020-03-31 19:29:02 +08:00 via Android
    tcp??究竟 tcp 包活英文是什么,现行互联网有这个东西么
    rdZZZ
        3
    rdZZZ  
       2020-03-31 21:39:53 +08:00
    有没有保熟机制 🐶
    andj4cn
        4
    andj4cn  
       2020-03-31 21:43:47 +08:00 via Android
    推荐一篇上古论文,end to end arguments in system design 。简单来说就是端到端通信可靠性只能靠应用层保证,具体可以看论文的阐述。
    hallDrawnel
        5
    hallDrawnel  
       2020-03-31 21:44:22 +08:00   ❤️ 2
    一个是应用层可用,一个是网络层可用,两者不等价。
    littlewing
        6
    littlewing  
       2020-03-31 21:44:43 +08:00 via iPhone
    1. 心跳包可能还顺带了一些信息
    2. tcp 连接可用并代表着应用可用
    andj4cn
        7
    andj4cn  
       2020-03-31 21:47:04 +08:00 via Android   ❤️ 1
    @andj4cn 底层不一定能完整定义应用层所要求的可靠性
    djoiwhud
        8
    djoiwhud  
       2020-03-31 21:54:25 +08:00
    就一点,tcp 协议自身的心跳机制是有迟滞的,而且应用层无法自己控制和确认。
    opengps
        9
    opengps  
       2020-03-31 21:55:57 +08:00 via Android
    我做过 socket 开发,我清除心跳的可靠性更高,更实时。
    tcp 某些默认检测机制时间太久,不适合用于存活检测
    23571113
        10
    23571113  
       2020-03-31 22:02:50 +08:00
    实际上很多性能要求很高的分布式系统的共识算法都是自己针对特定情况实现了网络层, 比如 polarfs 利用 dpdk 技术完全没有走内核网络栈, 还有 2019OSDI best paper 的那个 eRPC 就是针对机房优化过的 UDP.
    qiayue
        11
    qiayue  
       2020-03-31 22:09:02 +08:00
    其中一个原因:
    一个连接如果长时间没有数据传输,运营商会切断这个连接
    cabing
        12
    cabing  
       2020-03-31 22:11:14 +08:00
    tcp 协议是操作系统内核里面的黑盒,心跳包可控。
    zmxnv123
        13
    zmxnv123  
       2020-04-01 00:20:56 +08:00 via iPhone
    Tcp 保活时间参数是在内核设置的,作用于整个物理机。
    sampeng
        14
    sampeng  
       2020-04-01 00:31:54 +08:00 via iPhone
    自己做过才知道相信自己比相信外部要强一百倍
    jinsongzhao
        15
    jinsongzhao  
       2020-04-01 00:37:44 +08:00
    具体写过就知道,根本没法和多播 UDP 比。TCP 是有连接的,只有被连接的服务器知道客户机器是否活着,被连服务器死了就玩完了。TCP 建立连接过程慢,开销大,不能快速知道其他机器是否存活,光这几点就足够了。而基于多播的 UDP,参与监听的服务器就能知道是否存活,客户机不需要到处找服务器建立连接,判断存活速度可以根据 UDP 包连续间隔。
    passerbytiny
        16
    passerbytiny  
       2020-04-01 01:24:51 +08:00   ❤️ 1
    tcp 没有保活机制,只有超时自动断线,而这个超时间隔是两小时。光靠 tcp,你连上之后拔网线,两端都要在两小时之后才知道中间挂了。
    b00tyhunt3r
        17
    b00tyhunt3r  
       2020-04-01 02:16:01 +08:00
    @123444a
    keep alive?
    pigmen
        18
    pigmen  
       2020-04-01 07:47:10 +08:00 via iPhone
    不懂就问 能不能建立一个 tcp 链接 通信,双方就类似 ping pong 的形式保活
    CallMeReznov
        19
    CallMeReznov  
       2020-04-01 08:06:22 +08:00
    可能业务死了活了死了活了都几轮了. TCP 都没反应过来.
    而且在高负载情况的下可能是雪上加霜.
    hand515
        20
    hand515  
       2020-04-01 08:53:26 +08:00
    @pigmen #18 可以啊
    simonlu9
        21
    simonlu9  
       2020-04-01 09:05:46 +08:00
    程序有可能假死状态的,比如发生死锁这样,但是 tcp 连接还是正常,所以要应用层来判断
    useben
        22
    useben  
       2020-04-01 09:18:06 +08:00
    @pigmen 心跳维持就是你说的, 不过不是另建一个连接,而是就在当前连接,发送心跳包
    fancy111
        23
    fancy111  
       2020-04-01 09:21:55 +08:00
    说实话,我都不知道你们在说什么,什么是 TCP 保活?这个词我都没听过。 另外心跳包难道不是发送基于 tcp 的消息吗?
    一群人回复的不知所云的东西。
    newmlp
        24
    newmlp  
       2020-04-01 09:23:05 +08:00
    因为可能出现,tcp 没断,应用死了
    jinsongzhao
        25
    jinsongzhao  
       2020-04-01 09:41:11 +08:00 via Android
    @pigmen 链接模式发个 ping 出去,要等对方告诉你是否成功,对方不回就等超时,因此效率很低,你还要加个多线程或异步判断 ping pong 是否卡顿或断了,你还不能广播你的状态,只有被连服务器知道你是不是嗝屁了,或者你连多台服务器,连多少台也很纠结吧
    Esen
        26
    Esen  
       2020-04-01 09:51:07 +08:00
    心跳包可防可控,具有很高的实用价值。
    HelloAmadeus
        27
    HelloAmadeus  
       2020-04-01 09:56:11 +08:00
    保活是指 TCP 的 KeepAlive ? KeepAlive 一是不是 TCP 标准里的东西, 二是还是太不容易控制了,要改操作系统配置,还会有坑。以前遇到过连接被负载均衡强制关了,没有正常关闭, 也没有发 RST, 发过去的包就直接被吞了,KeepAlive 就不能处理这种情况。
    silenzio
        28
    silenzio  
       2020-04-01 09:58:15 +08:00   ❤️ 1
    心跳是要保证你的应用层没有崩溃, 而不是网络连接没有崩溃
    实际情况就是即使你的一些 service 线程崩了, 或者队列阻塞了, tcp 连接还是存活的, 你无法从 tcp 层面上的心跳来确保你的服务是正常的
    一个合格的心跳应该在你的应用层, 把你的应用层关键逻辑都走一遍, 对方收到了心跳, 就任务你的主要服务都是正常的, 不用进行错误处理
    cortexm3
        29
    cortexm3  
       2020-04-01 10:01:38 +08:00
    保活,Tcp 的 keepalive 。需要设置相关的参数,包括探针时间,数量,探针间隔等。
    我记得公司(工业领域,非 IT)通信协议的相关文档,其中就有建议在应用层使用心跳机制替代 keepalive 。
    abcbuzhiming
        30
    abcbuzhiming  
       2020-04-01 10:03:18 +08:00
    tcp 保活,默认 2 小时发 1 次,你用这种,噗。。。
    whywhywhy
        31
    whywhywhy  
       2020-04-01 10:51:38 +08:00
    @abcbuzhiming 哈哈哈,我之前也查到这个,基本没有可靠可颜。。
    whywhywhy
        32
    whywhywhy  
       2020-04-01 10:54:51 +08:00
    @123444a TCP 是目前互联网最为广泛的几个传输协议之一,工作在网络模型的第四层,保活、心跳都是开发者要考虑到的问题,所以……这个属于基础知识了。。
    fuis
        33
    fuis  
       2020-04-01 11:02:53 +08:00
    应用层跟协议层是两回事。TCP 连接可用不意味着应用可用。
    presoul
        34
    presoul  
       2020-04-01 12:52:33 +08:00 via Android
    @qiayue 是的
    clrss
        35
    clrss  
       2020-04-01 13:37:57 +08:00
    TCP keepalive 各项参数都能在应用里调, 时间到不是问题.

    “当 Send-Q 不为 0 时(见 ss -nat), tcp_keepalive 不会发送 probe 包, 即不会触发 TCP 超时.”

    这个问题很大.
    snnn
        36
    snnn  
       2020-04-01 15:05:36 +08:00 via Android
    楼上说了这么多,估计 10 里有 9 个都不知道,TCP 可以灾难恢复,拔掉网线再插上一切如旧。TCP 自带的 keepalive 机制会毁掉这个
    paoqi2048
        37
    paoqi2048  
       2020-04-01 17:49:01 +08:00
    你这连接保熟吗?
    roundgis
        38
    roundgis  
       2020-04-01 20:13:06 +08:00
    @123444a keep-alive? 这个参数只有一个推荐值,我知道有些嵌入式设备会把它调整为 10 秒用来取代应用层的心跳


    不过我个人还是觉得在应用层设置心跳机制更可靠
    horkooo
        39
    horkooo  
       2020-04-02 18:23:05 +08:00 via Android
    心跳也需要 tcp 连接
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2490 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 15:57 · PVG 23:57 · LAX 07:57 · JFK 10:57
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.