Netty通信框架功能设计

源码部分请见Netty的高级用法(一)

功能描述

通信框架承载了业务内部各模块之间的消息交互和服务调用,它的主要功能如下:

  • 基于Netty的NIO通信框架,提供高性能的异步通信能力
  • 提供消息的编解码框架,可以实现POJO的序列化和反序列化
  • 消息内容的防篡改机制
  • 提供基于IP地址的白名单接入认证机制
  • 链路的有效性校验机制
  • 链路的断连重连机制

通信模型

在这里插入图片描述

1.客户端发送应用握手请求,携带节点ID等有效身份认证信息
2.服务端对应应用握手请求消息进行合法性校验,包括节点ID有效性校验、节点重复登录校验和IP地址合法性校验,
校验通过后,返回登录成功的应用握手应答消息
3.链路建立成功之后,客户端发送业务消息
4.链路成功之后,服务端发送心跳消息
5.链路建立成功之后,客户端发送心跳消息
6.链路建立成功之后,服务端发送业务消息
7.服务端退出时,服务端关闭连接,客户端感知对方关闭连接后,被动关闭客户端连接

备注:需要指出的是,协议通信双方链路建立成功之后,双方可以进行全双工通信,无论是客户端还是服务端,都可以主动发送请求消息给对方,通信方式可以是TWO WAY或者ONE WAY.双方之间的心跳采用Ping-Pong机制,当链路处于空闲状态时,客户端主动发送Ping消息给服务端,服务端接收到Ping消息后发送应答消息Pong给客户端,如果客户端连续发送N条Ping消息都没有接收到服务器返回的Pong消息,说明链路已经挂死或者对方处于异常状态,客户端主动关闭连接,间隔周期T后发起重连操作,直到重连成功

消息定义

消息定义包含两部分:消息头+消息体。
在消息的定义上,因为是同步处理模式,不考虑应答消息需要填入请求消息ID,所以消息头中只有一个消息的ID,如果要支持异步模式,则请求消息头和应答消息头最好分开设计,应答消息头中除了包含本消息的ID外,好应该包括请求消息ID,以方便请求消息的发送方,根据请求消息ID做对应的业务处理

  • Netty消息定义表
    +
  • 消息头定义(Header)
    在这里插入图片描述

链路的建立

客户端的说明如下:如果A节点需要调用B节点的服务,但是A和B之间还没有建立物理链路,则由调用方主动发起连接,此时,调用方为客户端,被调用方为服务端。考虑到安全,链路建立需要通过IP地址或者号段的黑白名单安全认证机制,比如,协议使用基于IP地址的安全认证,如果有多个IP,通过逗号进行分割。在实际的商用项目中,安全认证机制会更加严格,例如通过密钥对用户名和密码进行安全认证客户端 与服务端链路建立成功之后,由客户端发送业务握手请求的认证消息,服务端接收到客户端的握手请求消息之后,如果IP校验通过,返回握手成功应答消息给客户端,应用层链路建立成功。握手应答消息中消息体为byte类型的结果:0:认证成功 -1:认证失败,服务端关闭连接链路建立成功之后,客户端和服务端就可以互相发送业务消息了,在客户端和服务端的消息通信过程中,业务消息体的内容需要通过MD5进行摘要防篡改

可靠性设计

  • 心跳机制。
    在凌晨等业务低谷时段,如果发生网络闪断、连接被Hang住等问题时,由于没有业务消息,应用程序很难发现。到了白天业务高峰期时,会发生大量的网络通信失败,严重的会导致一段时间进程内无法处理消息。为了解决这个问题,在网络空闲时采用心跳机制来检测链路的互通性,一旦发现网络故障,立即关闭链路,主动重连。当读或者写心跳消息发生I/O异常的时候,说明已经中断,此时需要立即关闭连接,如果时客户端,则需要重新发起连接,如果是服务端,需要清空缓存的半包信息,等到客户端重连
  • 空闲的连接和超时。
    检测空闲连接以及超时对于及时释放资源来说是至关重要的。由于这是一项常见的任务,Netty特地为它提供了几个ChannelHandler实现。IdleStateHandler当连接空闲时间太长时,将会触发一个IdleStateEvent时间。然后,可以通过在ChannelInboundHandler中重写userEventTriggered()方法来处理该IdleStateEvent时间ReadTimeoutHandler如果在指定的时间间隔内没有收到任何的入站出局,则抛出一个ReadTimeoutException并关闭对应的Channel.可以通过重写ChannelHandler中的exceptionCaught()方法来检测该Read-TImeoutException
  • 重连机制。
    如果链路中断,等到INTERVAL时间后,由客户端发起重连操作,如果重连失败,间隔周期INTERVAL后再次发起重连,直到重连成功。为了保证服务端能够有重组的时间释放句柄资源,在首次断连时客户端需要等待INTERVAL时间之后再发起重连,而不是失败后立即重连。为了保证句柄资源能够及时释放,无论什么场景下重连失败,客户端必须保证自身的资源被及时释放,包括但不限制SocketChannel、Socket等重连失败后,可以打印异常堆栈信息,方便后续的问题定位
  • 重复登录保护。
    当客户端握手成功之后,在链路处于正常情况下,不允许客户端重复登录,以防止客户端在异常情况下反复重连导致句柄资源被耗尽。服务端接收到客户端的握手请求消息之后,对IP地址进行合法性校验,如果校验成功,在缓存的地址列表中查看客户端是否已经登录,如果登录,则拒绝重复登录,同时关闭TCP链路,并在服务端的日志中打印握手失败的原因。客户端接收到握手失败的应答消息之后,
    关闭客户端的TCP连接,等待INTERVAL时间之后,再次发起TCP连接,直到认证成功

实现设计

在这里插入图片描述

  • 前期准备。
    定义好消息有关的实体类,为了防篡改,消息体需要进行摘要,可以使用MD5、SHA-1和SHA-256.
    还可以对MD5进行额外的加盐摘要,序列化框架可以使用Kryo
  • 服务端。
    最先安装的当然是解决粘包半包问题的Handler,很自然,这里应该用LengthFieldBasedFrameDeocder进行编码,
    为了实现方便,可以在消息报文中不附带消息的长度,由Netty帮我们在消息报文的最开始增加长度,所以编码器选择LengthFieldPrepender.接下来自然就是序列化和反序列化,服务端需要进行登录检查、心跳应答、业务处理,对应着三个Handler,于是分别安装LoginAuthRespHandler、HeartBeatRespHandler、ServerBusiHandler.为了节约网络和服务器资源,如果客户端长久没有发送业务和心跳报文,我们认为客户端出现了问题,需要关闭这个连接,我们引入Netty的ReadTimeoutHandler,当一定周期内(默认值50s,我们可以设定为15s)没有读取到对方任何消息时,
    会触发一个ReadTimeoutException,这时我们检测到这个异常,需要主动关闭这个链路,并清楚客户端登录缓存信息,等待客户端重连
  • 客户端。
    最先安装的当然是解决粘包和半包问题的Handler,同样这里应该用LengthFieldBasedFrameDecoder进行解码,编码器选择LengthFieldPrepender,接下来就是序列化和反序列化。客户端需要主动发出认证请求和心跳请求。在TCP三次握手,链路建立后,客户端需要进行应用层的握手认证,才能使用服务,这个功能由LoginAuthReqHandler负责,而这个Handler在认证通过之后其实就没用了,送一在认证通过后,可以将这个LoginAuthReqHandler移除(其实服务端的认证应答LoginAuthRespHandler同样也可以移除)。对于发出心跳请求有两种实现方式,一是定时发出,这种方式其实有浪费的情况,因为如果客户端和服务器正在正常通信,其实是没有必要发送心跳的;第二种方式就是,当链路写空闲时,为了维持通道,避免服务器关闭链接,发出心跳请求,如果要实现这一点,需要在整个pipeline的最前面安装一个CheckWriteIdleHandler进行写空闲检测,设置一个空闲时间,一般取服务器读空闲时间15s的一半,然后再安装一个HeartBeatReqHandler,因为写空闲会触发一个FIRST_WRITER_IDLE_STATE_EVENT入站事件,我们在HeartBeatReqHandler的userEventTriggered方法中捕捉这个事件,并发出心跳请求报文,也可以考虑双向心跳
    (即使客户端向服务器发送心跳请求,是服务器也向客户端发送心跳请求),这里我们可以让客户端安装一个ReadTimeoutHandler,来检测服务器是否存活,捕捉ReadTimeoutException后提示调用者,并关闭通信链路,触发重连机制
  • 测试。
    1.正常情况
    2.客户端宕机,服务器应能清楚客户端的缓存信息,允许客户端重新登录
    3.服务器宕机,客户端应能发起重连
    4.在LoginAuthRespHandler中进行注释,可以模拟当服务器不处理客户端的请求时,
    客户端在超时后重新进行登录
  • 功能的增强。
    作为一个通信框架,支持诊断也是很重要的,所以我们可以在服务端单独引入一个MetricsHandler,
    可以提供,目前在线Channel数、发送队列积压消息数、读取速率、写出速率相关数据,以方便应用
    方对自己的应用的性能和繁忙程度进行检查和调整。当然对于一个通信框架还可以提供SSL安全访问、流控、I/O线程和业务线程分离、参数的可配置化等等功能

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/394478.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用 apt 源安装 ROCm 6.0.x 在Ubuntu 22.04.01

从源码编译 rocSolver 本人只操作过单个rocm版本的情景,20240218 ubuntu 22.04.01 1,卸载原先的rocm https://docs.amd.com/en/docs-5.1.3/deploy/linux/os-native/uninstall.html # Uninstall single-version ROCm packages sudo apt autoremove ro…

IO 流分类

一、File File 类(磁盘操作)可以用于表示文件和目录的信息,但是它不表示文件的内容。递归地列出一个目录下所有文件: public static void listAllFiles(File dir) {if (dir null || !dir.exists()) {return;}if (dir.isFile())…

收藏 数据结构链表的知识点总结

数据结构链表知识点总结 1. 链表的基本概念 - 链表是一种线性数据结构,由一系列节点(或元素)组成。 - 每个节点包含两部分:数据域和指针域(或称为链接)。 - 指针域存储指向下一个节点的地址&#xff0c…

扶贫助农|基于springboot的扶贫助农系统设计与实现(源码+数据库+文档)

扶贫助农系统目录 目录 基于springboot的扶贫助农系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、用户信息管理 2、扶贫任务管理 3、论坛信息管理 4、扶贫公告管理 四、数据库设计 1、实体ER图 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐…

java面试多线程篇

文章说明 在文章中对所有的面试题都进行了难易程度和出现频率的等级说明 星数越多代表权重越大,最多五颗星(☆☆☆☆☆) 最少一颗星(☆) 1.线程的基础知识 1.1 线程和进程的区别? 难易程度:☆☆…

JAVA--泛型(Generic)

目录 1. 泛型概述 1.1 生活中的例子 1.2 泛型的引入 2. 使用泛型举例 2.1 集合中使用泛型 2.1.1 举例 2.2 比较器中使用泛型 2.2.1 举例 2.2.2 练习 2.3 相关使用说明 3. 自定义泛型结构 3.1 泛型的基础说明 3.2 自定义泛型类或泛型接口 3.2.1 说明 3.2.2 注意 …

LabVIEW智能监测系统

LabVIEW智能监测系统 设计与实现一个基于LabVIEW的智能监测系统,通过高效的数据采集和处理能力,提高监测精度和响应速度。系统通过集成传感器技术与虚拟仪器软件,实现对环境参数的实时监测与分析,进而优化监控过程,提…

平滑升级旧版nginx,使其支持健康检测模组

nginx是部署在华为欧拉的docker容器中,版本是2203sp1.x86_64 查看旧版nginx的版本与编译配置信息: nginx -Vnginx version: nginx/1.14.1 built by gcc 8.3.1 20191121 (Red Hat 8.3.1-5) (GCC) built with OpenSSL 1.1.1g FIPS 21 Apr 2020 (running …

解决Ubuntu下网络适配器桥接模式下ping网址不通的情况

问题反应:ping不通网址 打开虚拟机中的设置,更改网络适配器为NAT模式 确定保存更改之后,退出输入如下命令。 命令1: sudo /etc/network/inferfaces 命令2: sudo /etc/init.d/network/ restart

SpringCloud-Config:分布式配置

10. Spring Cloud Config 分布式配置 Dalston.RELEASE Spring Cloud Config为分布式系统中的外部配置提供服务器和客户端支持。使用Config Server,您可以在所有环境中管理应用程序的外部属性。客户端和服务器上的概念映射与Spring Environment和PropertySource抽象…

电商云平台系统的设计与实现

随着电商市场的不断发展,越来越多的企业和个人选择通过电商平台开展业务。为了更好地满足电商市场的需求,一个高效、安全、可扩展的电商云平台系统是必不可少的。本文将介绍电商云平台系统的设计与实现。 1. 系统架构设计 电商云平台系统的架构设计主要…

SSTI模板注入漏洞(vulhub 复现)

首先了解模板引擎: 模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,利用模板引擎来生成前端的html代码,模板引擎…

JS加密解密之JS广告漂浮代码分析

前言 之前有个客户要求帮忙复刻一份广告漂浮代码,我看了下,目标站的广告代码是通过了JS加密后的,经过我解密还原后分析了一下该代码的作用如下。 ;var _0xodDddd,_0xodD_[_0xodD],_0x1d02[_0xodD,\x73\x54\x69\x6d\x65,\x6c\x6f\x61\x64\x5…

Vue3 provide + inject

provide&#xff1a;提供一个值&#xff0c;可以在应用中的所有后代组件中注入使用。 官方文档&#xff1a;应用实例 API | Vue.js 应用实例 API | Vue.jsVue.js - 渐进式的 JavaScript 框架https://cn.vuejs.org/api/application.html#app-provide 使用示例 祖先组件 <…

『随处指挥』:用这款APP,世界听你的!

在这个科技日新月异的时代&#xff0c;我们的生活被各种手机软件所包围。几乎每个人都有一个甚至多个手机&#xff0c;你是否也有遇到过需要远程操作自己某一台手机的场景呢&#xff1f;今天&#xff0c;我要向大家推荐一款神奇的手机远程操作神器&#xff0c;让你可以随时随地…

【设计模式】4、策略模式

文章目录 一、问题二、解决方案2.1 真实世界的类比2.2 策略模式结构2.3 适用场景2.4 实现方式2.5 优缺点2.6 与其他模式的关系 三、示例代码3.1 go3.2 rust 策略模式是一种行为设计模式&#xff0c;它能定义一系列算法&#xff0c;把每种算法分别放入独立的类中&#xff0c;以是…

[Flask]SSTI1 buuctf

声明&#xff1a;本篇文章csdn要我一天发两篇所以我来水的 跟ssti注入的详细知识我这里写了 https://blog.csdn.net/weixin_74790320/article/details/136154130 上面链接我复现了vulhub的SSTI&#xff0c;其实本质上是一道题 然后我们就用{{.__class__}}看类的类型&#xf…

政安晨:【完全零基础】认知人工智能(三)【超级简单】的【机器学习神经网络】—— 三层神经网络示例

知识准备 咱们还没有演示过使用矩阵进行计算得到经由神经网络馈送的信号&#xff0c;我们也没有演示过多于2层的神经网络示例&#xff0c;在这篇文章里&#xff0c;咱们将构建一个三层神经网络的示例&#xff0c;并观察如何处理中间层的输出以作为最后第三层的输入&#xff0c…

百度智能云分布式数据库 GaiaDB-X 与龙芯平台完成兼容认证

近日&#xff0c;百度智能云的分布式关系型数据库软件 V3.0 与龙芯中科技术股份有限公司的龙芯 3C5000L/3C5000 处理器平台完成兼容性测试&#xff0c;功能与稳定性良好&#xff0c;获得了龙架构兼容互认证证书。 龙芯系列处理器 通用 CPU 处理器是信息产业的基础部件&#xf…

【CSS】设置文字(文本)的渐变色

# 渐变色 文字 第一步 设置渐变颜色 background: linear-gradient(278.83deg, #5022bd 31.42%, #8636d1 75.55%); // 先设置渐变色背景&#xff1b; 第二步 设置颜色的使用范围 background-clip: text; // 背景被裁剪成文字的前景色。 -webkit-background-clip: text; 第三步…
最新文章