首页 > 其他分享 >场景之心跳应用

场景之心跳应用

时间:2022-08-28 22:45:27浏览次数:66  
标签:场景 注册 TCP 发送 应用 心跳 连接 服务端

一、心跳概述

常见的IM类应用,比如游戏,直播,聊天室或者客服系统,一般都要依靠服务端做消息中转,将从发送方接受的消息推送给接收方,为保证可靠,快速到达对端,⼤部分IM使⽤长连接建⽴通道,并且建⽴TCP连接和用户设备的映射关系,长连接⼀旦建⽴,就会⼀直存在,除非意外被中断,并依靠该链接接受和推送消息。
心跳机制存在的意义:这个长连接并不是物理意义上的连接,⽽是⼀个无感知的虚拟TCP连接,即使断开两端也不会感知,因此心跳机制来让连接在出现问题的时候,迅速的让对端感知到,心跳要做的就是快速不间断的识别来探测连接可⽤性。

1、心跳机制在长连接维护的必要性

  • 降低服务端维持连接的开销:服务端除了维持⽹络连接和用户设备的映射之外,还会保存⼀些包括app版本号,os系统类型等信息,这些信息第⼀次建立连接发送,以后都维持到服务端缓存,如果存在⼤量的断开的连接,就会造成具柄和缓存的浪费,因此⼼跳机制保证了在连接断开后尽早的清理服务端连接使⽤的资源。

  • ⽀持客户端断线重连:⼀般移动设备连接的都是运营商的内网,⽽IPv4地址总共约为43亿个,因此为了节省IP地址资源,运营商通常会采⽤NAT⼿段,为联⽹设备分配内⽹IP,变成了内网IP:port-外网IP:port的映射,使得内网IP的⼿机能和外网联通,但为了提⾼IP利⽤率,如果⼀个连接⼀段时间没有数据收发,运营商就会把这个映射从NAT映射表清除掉,为了避免长连接被被运营商下掉,就需要长跳机制定期发送⼀些数据对连接让运营商以为这个链接还在用从而进行保活。

2、心跳实现方式

一般有三种:

  • TCP层⾯的keep-alive,发送端在发送完数据给接收方之后,接收方会启动一个超时计时器,每当计时器超时就会发送探测报⽂给发送方,心跳包不携带数据,累计10次心跳包没有回应则认为链接失效断开了。协议栈实现使⽤资源最少,但是心跳间隔设置不灵活,TCP的keep-Alive只代表链接层,不代表应⽤层可⽤,比如代码死锁,同样tcp链接可用,但是服务已经不可用了。
  • 应⽤层心跳:应⽤层⼼跳实际上就是客⼾端每隔⼀定时间间隔,向IM服务端发送⼀个业务层的数据包告知自⾝存活。相比TCP心跳,更灵活设置心跳间隔和更可⽤状态的保活。
  • 智能心跳:避免NAT超时,只能将心跳间隔设置为小于所有网络环境下NAT超时的最短时间。但是定期心跳,会有CPU和网络流量的浪费,因此提出智能心跳,根据网络环境自动调整心跳间隔的时间,逐渐逼近NAT超时临界点,优化心跳间隔。

3、总结

⼼跳作⽤:

  • 降低服务端连接维护⽆效连接的开销
  • ⽀持客⼾端快速识别⽆效连接,快速重连
  • 连接保活,防⽌被运营商NAT超时端开。

问题:可否结合TCP的keep-Alive和应⽤层心跳使⽤?
tcp的keep-alive解决网络可⽤性,应⽤层keep-alive解决⽹络和服务可⽤性,但是应⽤层无法区分网络还是服务问题,因此加上tcp心跳包可以进⼀步区分,tcp心跳探测到链接正常,而此时应用层通信出现问题,则可能是服务出现问题。

二、心跳实现示例

1、注册中心

微服务项目中为了让客⼾端知道具体服务部署的地址,通常要使用服务注册中心。

(1)、注册中心解决问题

  • 提供服务地址的存储
  • 存储内容发⽣变化,变更内容推送到客⼾端

通过注册中心,即使需要扩容,或者摘除节点,也不⽤重启客⼾端服务器。

  • 客户端会与注册中心建⽴连接,并且告诉注册中心,它对哪⼀组服务感兴趣;
  • 服务端向注册中心注册服务后,注册中心会将最新的服务注册信息通知给客⼾端;
  • 客⼾端拿到服务端的地址之后就可以向服务端发起调⽤请求了。

(2)、服务状态如何管理

主动探测:服务要打开⼀个端口,然后由注册中心每隔⼀段时间(比如30秒)探测这些端口是否可⽤,如果不可⽤就从服务列表摘除。
问题:

  • 服务节点都需要开放⼀个统⼀端⼝给注册中心探测,端⼝可能被互相占⽤。
  • 服务器部署很多,探测对于注册中⼼的代价也很高,服务不可⽤的时候还会有延迟。

心跳机制:服务节点注册到服务中心后,会按照⼀定的时间间隔向注册中心发送心跳包,注册中心收到后会更新最新续约时间,启动⼀个定时器,如果⼀定时间还没有收到心跳,就认为服务不可⽤。服务也需要检测是否存活,那么也可以考虑使⽤心跳机制来检测

2、聊天室心跳应用和实现

在即时通信系统中,比如聊天室,一般都是采用发送方与服务器建立一条TCP连接,接收方也会与服务器建立一条TCP连接。
首先用户有⼀个登陆的过程:

  • tcp客户端与服务端通过三次握⼿建立tcp连接。
  • 基于该连接客户端发送登陆请求。
  • 服务端对登陆请求进⾏解析和判断,如果合法,就将当前用户uid和标识当前tcp连接的socket描述符(也就是fd)建⽴映射关系。
  • 这个映射关系⼀般是保存在本地缓存中。
  • 然后当服务端收到要发送给这个用户的消息时,先从缓存中根据uid查找fd,如果找到,就基于fd将消息推送出去。

具体的即使通信系统应用场景可以了解:实时在线在线人数

(1)、心跳实现逻辑

因为要基于该TCP连接发送消息,所以要先保证该连接的可靠性,因此要使用如上中所说要通过心跳及时的探测到链接的是否仍有效。
逻辑如下:

  • 用户与服务器建立TCP连接
  • 用户每隔几秒向服务器发送心跳包
  • 服务端在收到心跳包之后,更新用户的最后在线时间
  • 服务端同时有一个定时脚本,定时脚本每隔一段时间执行一次扫描所有的用户的最后在线时间与现在时间对比,如果超过设置的超时时间,则重连或者清空相应服务端缓存资源给出对应操作。

(2)、hash结构具体实现

实现上:可以用redis的hash结构,配合记录所有的用户的最后在线时间。

hash结构中字符串是一个key对应一个value,value中通常只有一个对应key的数据,而hash中,把很多个数据(field:value)存到一个value中,Hash类型可以看成具有String Key和String Value的map容器添加和删除操作都是O(1)(平均)的复杂度,每个hash可以存储232-1 键值对(40多亿),操作复杂度和存储上限一般不会有问题。
hash的key为chat-room,表示这是聊天室key。
当用户发送心跳,设置hash字段,field为user_id,value为当前系统时间戳

hset chat-room user_id time.Now().Unix()

服务端定时脚本检测逻辑如下

res = hgetall chat-room # 将hash所有字段fields和value保存在res字典中
for field, value := range res: # 遍历所有字段,也就是查看所有用户的上一次心跳时间
    if time.Now().Unix() - value > 60 * 3:  # 如果上一次心跳距离现在超过3分钟,则认为连接断开,连接资源。
        clearConnect()

标签:场景,注册,TCP,发送,应用,心跳,连接,服务端
From: https://www.cnblogs.com/welan/p/16634303.html

相关文章

  • 项目中索引的真实应用场景-2022新项目
    一、业务场景项目开发中,数据存储是一定少不了的,不管是存储关系型数据还是还是非关系型数据。可选择的范围也很广,比如mysql,postgresql,oracle,mongodb等等。一般都是根......
  • 学习ASP.NET Core Blazor编程系列二——第一个Blazor应用程序(上)
    学习ASP.NETCoreBlazor编程系列一——综述一、概述      Blazor是一个生成交互式客户端WebUI的框架: 使用C#代替JavaScript来创建信息丰富的交互式......
  • HCIP-防火墙单包攻击防范与应用2_URPF
    一,拓扑1.1实验拓扑 1.2拓扑介绍配置OSPF使得全网互通,使用Cloud1桥接一台linux,发送修改源地址的欺骗报文。基于源地址欺骗发起的网络攻击,已经成为Internet上一种非......
  • 凝思操作系统变电站应用软件案例
    软件名称:linux系统平台上国产化应用微机五防系统开发语言:c++开发GUI工具:wxWidgets3.1.5、agg操作系统:ubuntu18.04LTS 及以上版本、 凝思6.0.80及以上版本  ......
  • web应用模式和api接口
    web应用模式:前后端不分离(客户端看到的内容和所有界面效果都是由服务端提供出来的)  2.前后端分离(把前端的界面效果(html,css,js分离到另一个服务端,python服务......
  • 嵌入式系统原理及应用教程课后习题(未完持续更新中)
    第一章:嵌入式系统概述1.1嵌入式系统的概念是什么?  以应用为中心、以计算机技术为基础、软件硬件可裁剪、适应应用系统对功能、可靠性、成本、体积、功耗严格要求的......
  • D_06 DotnetCore.CAP在项目中的应用
    描述在项目中,DotnetCore.CAP可以作为分布式事务、消息队列的解决方案,详见官方文档:https://cap.dotnetcore.xyz/,此处不过多的讲解。本文主要讲解官方文档没有说明,但是在实......
  • 疾速瓜牛 Linux三剑客 之 sed学习与应用
    sed,是streameditor的缩写,顾名思义,就是个非交互式行编辑器,有以下特点:它能执行与编辑器vi和ex相同的编辑任务sed编辑器没有提供交互式使用方式,使用者只能在命令行......
  • JDBC应用
    JDBC应用记录JDBC的学习笔记,为后期使用JDBC建立一个简单的速查页面,省去中间的推导等池:DruidDBUtil:ApacheCommonsDbUtils也作为八股文的速查数据库连接的基本步......
  • 图解AspNetCore和Furion(1):应用启动
    一、和AspNetCore5相比,从6开始,将Program和Startup类合并,直接在入口类中启动服务和中间件。同时,项目可以启动miniApi,直接在Program中设置路由和控制器。实际项目中,还是推荐......