HBT机制

    xiaoxiao2024-12-21  5

    网络中的接收和发送数据都是使用操作系统中的SOCKET进行实现。但是如果此 套接字已经断开,那发送数据和接收数据的时候就一定会有问题。可是如何判断这个套接字是否还可以使用呢?这个就需要在系统中创建心跳机制。其实TCP中已经为我们实现了一个叫做心跳的机制。如果你设置了心跳,那TCP就会在一定的时间(比如你设置的是3秒钟)内发送你设置的次数的心跳(比如说2次),并且此信息不会影响你自己定义的协议。所谓“心跳”就是定时发送一个自定义的结构体( 心跳包或心跳帧),让对方知道自己“在线”。 以确保链接的有效性。 所谓的心跳包就是客户端定时发送简单的信息给服务器端告诉它我还在而已。代码就是每隔几分钟发送一个固定信息给服务端,服务端收到后回复一个固定信息如果服务端几分钟内没有收到客户端信息则视客户端断开。比如有些通信软件长时间不使用,要想知道它的状态是在线还是离线就需要心跳包,定时发包收包。发包方:可以是客户也可以是服务端,看哪边实现方便合理。一般是客户端。服务器也可以定时轮询发心跳下去。 心跳包之所以叫心跳包是因为:它像心跳一样每隔固定时间发一次,以此来告诉服务器,这个客户端还活着。事实上这是为了保持 长连接,至于这个包的内容,是没有什么特别规定的,不过一般都是很小的包,或者只包含包头的一个空包。 在TCP的机制里面,本身是存在有心跳包的机制的,也就是TCP的选项。系统默认是设置的是2小时的心跳频率。但是它检查不到机器断电、网线拔出、防火墙这些断线。而且逻辑层处理断线可能也不是那么好处理。一般,如果只是用于保活还是可以的。心跳包一般来说都是在逻辑层发送空的包来实现的。下一个定时器,在一定时间间隔下发送一个空包给客户端,然后客户端反馈一个同样的空包回来,服务器如果在一定时间内收不到客户端发送过来的反馈包,那就只有认定说掉线了。只需要 send或者recv一下,如果结果为零,则为掉线。 但是,在 长连接下,有可能很长一段时间都没有数据往来。理论上说,这个连接是一直保持连接的,但是实际情况中,如果中间节点出现什么故障是难以知道的。更要命的是,有的节点( 防火墙)会自动把一定时间之内没有数据交互的连接给断掉。在这个时候,就需要我们的 心跳包了,用于维持长连接,保活。在获知了断线之后,服务器逻辑可能需要做一些事情,比如断线后的 数据清理呀,重新连接呀当然,这个自然是要由逻辑层根据需求去做了。总的来说,心跳包主要也就是用于长连接的保活和断线处理。一般的应用下,判定时间在30-40秒比较不错。如果实在要求高,那就在6-9秒 HBT数据发送频率由服务端来控制, 当服务器繁忙时可把采集间隔拉大 默认客户端每30s发送一次HBT, 值域[30s-120s], 超出取默认. 1.2 当有需要上报的数据( 报错消息,统计数据),由相关的程序初始化一个HBTEntry 对象,并设置属性,记录相关数据,放入HBT上报池中. // HBTEntry属性包含type, data(应用相关数据),timestamp 1.3 HBT上报池为客户端维护的数组,数组大小默认1024, 值域[512-2048] 1.3.1报警机制: 如果HBT上报池的大小超过数组大小的90%则记录一条errorlog 1.3.2容错机制: 客户端检测上报池超出1024不再存储, 并记录一条errorlog 1.4 每次发生HBT时 , 检查上报池中的数据,并从上报池中取出需要处理的数据(上限100条),  根据与服务端协议的数据结构构建出需要上报的数据格式和请求头信息上报服务端,成功后清除已上报的数据, 如失败则等待下一次HBT请求 客户端上报数据结构

    请求头大小由服务端web server配置文件决定, 默认16k 请求头信息 {     "vresion":"1", “system_config_version”:”1”, // 系统配置项版本 “user_config_version”:”1”, // 用户配置项版本 “user_config_data”:”{}”, // 用户配置项数据 “system_config_data”:”{}”, // 系统配置想数据 “report_count”:100, // 上报数据条数,可用来观察客户端HBT数据产生是否异常 “queue_count”:24, // 客户端队列中数据的条数,可用来观察客户端HBT数据产生是否异常 “device_info”:”{}”,  // 用户环 境信息 “spare”:” string” // 保留字段 } 2.1 服务端根据HBT请求头中的用户配置项版本号判断是否需要更新用户配置项 2.2 每一次的HBT,同步更新用户环境信息和最后登录时间. 2.3通过HBT上报的report_count和queue_count判断客户端请求池的大小是否异常(超过90%), 如果有异常则记录一条log到表中 2.4客户端上报数据 {     "data":[         { “type”:”error_info”,             "data":[                 {                     "type":"breakdown",                     "info":"...",                     "uid":123123123,                     "nickname":"张三",                     "mobile":13838384438                     "device_type":"iOS",                     "device_model":"iPhone 6",                     "device_version":"9.3.2",                     "network":"wifi",        “timestamp”:13244444444                 }             ]         }     ] } 2.5 客户端上报给服务端的数据直接存储到HBT表,根据HBTEntry的type由指定的守护进程去处理.(每次处理都以文件的形式记录下处理的最后一个id, 并更新该条数据的处理状态和处理时间) 2.6 HBT数据表基本结构 字段名 类型 说明 id int 自增列 type varchar HBTEntry数据类型 data text HBTEntry数据 status tinyint 数据处理状态, 0:待处理, 1: 处理成功, 2: 处理失败 add_time int 数据写入时间 process_time int 数据处理花费时间 update_time int 数据最后处理完成时间 create_time int 客户端HBTEntry对象生成时间  // HBT数据表按照月份分片: hbt201609  3 服务端下发数据 3.1 获取用户配置项和系统配置项, 并构建到返回头信息中 头信息 { "vresion":"1", “system_config_version”:”1”, “user_config_version”:”1”, “user_config_data”:”{}”, “system_config_data”:”{}”, “spare”:”string” }  3.2 数据下发相关逻辑: 客户端根据 type调用相关程序处理对应的data数据, 实现伪推送. 每次收到HBT时到redis中查找是否有需要下发的数据, 如果有就下发到客户端, 下发完成后删除redis中已下发的数据. 如果查询出的数据超过100条, 在系统log表中存储一条异常记录 3.3 服务端下发数据结构 {     "data":[         { “type”:”” “data”:{} }     ],     “errorcode”:0,     "timestamp":1231231231 }

    转载请注明原文地址: https://ju.6miu.com/read-1294827.html
    最新回复(0)