实验
准备工作:
- 内核参数: 观察系统是否存在以下的内核参数,由于是协议栈支持,不一定能在所有系统上实现。

- 本次试验采取netcat作为服务端,客户端设置套接字选项进行调用,并通过wireshark进行观察。
Step1. 启动netcat

Step2. 运行客户端代码
#!user/bin/python
# _*_ coding: utf-8 _*_
# @File : test_tcp_healthcheck.py
# @Version : 1.0
# @Author :
# @Email :
# @Time : 2020/03/27 15:08:56
#Description:
import time
import unittest
import socket
class TcpHealthCheckTestCase(unittest.TestCase):
def setUp(self):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
def test_send_health(self):
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # 开启tcp keepalive
self.sock.setsockopt(socket.SOL_TCP, socket.TCP_KEEPIDLE, 10) # 开启空闲探测机制
self.sock.setsockopt(socket.SOL_TCP, socket.TCP_KEEPINTVL, 2) # 开启探测的间隔时间
self.sock.setsockopt(socket.SOL_TCP, socket.TCP_KEEPCNT, 2) # 开启探测的次数
self.sock.connect(("172.17.220.146", 9911))
self.sock.send(b"1234")
time.sleep(60)
self.sock.close()
if __name__ == "__main__":
unittest.main()
Step3. 启动wireshark并设置相应的条件
可以发现探测客户端会间隔一段时间进行探活


类型(心跳), 长度, 时间戳

问题:
为什么有tcp层的心跳,还需要实现应用层的心跳机制?
假设我的心跳的目的是为了维持连接的话,反正服务端上存在过大冗余的连接数,那么可以在服务端启动心跳做探测,但是这块存在两个问题。
- TCP协议包含keep alive,但不是所有系统设备可以支持。
- TCP keepalive属于tcp协议包,在连接之间有proxy或者nat,他们可能不会处理tcp keep alive。
假设我平台支持keep alive,但我想实施心跳的目的是探测服务端是否可用,是否处理不可工作状态,这个时候结合业务断开tcp连接,由客户端做异常处理。应用自实现心跳最大的好处,就是能适应复杂的网络结构。