InfiniGate自研网关实现思路一

1.HTTP请求会话协议处理

运用Netty对HTTP请求信息的协议转换,构建网关会话服务,简单响应HTTP请求信息到页面。

  • 之所以称之为会话,是因为一次 HTTP 请求,就要完成;建立连接、协议转换、方法映射、泛化调用、返回结果等一些列操作。而在这些操作过程中的各类行为处理,其实也类似于ORM框架,只不过一个是对数据库的处理,一个是对 RPC服务的处理所有的学习都是举一反三,核心的设计万变不离其宗!
  • 此外之所以要单独创建出一个 api-gateway-core 的工程,是因为我们要把这个工程独立于各种容器,例如它并不是直接与 SpringBoot 一起开发,因为那样会让组件失去灵活性。它的存在更应该像是一个 ORM 框架,可以独立使用,谁也都可以结合

具体实现:

1.定义了一个继承了SimpleChannelInboundHandler<T>的BaseHandler<T>表明为入站处理器,里面定义了一个抽象方法session(也就是会话操作),接下来在handlers包中定义了一个自定义的handler继承BaseHandler<T>,T泛型为FullHttpRequest,里面对session方法进行重写,模拟http请求的响应,最后完成一次会话。

2.定义一个用于初始化channel中的处理器的类SessionChannelInitializer,继承ChannelInitializer<SocketChannel>,重写了initChannel方法,里面向channel添加了自定义的handler以及对http请求编解码的handler。

3.服务创建:创建一个启动会话服务的类SessionServer实现了Callable<Channel>接口,让服务在线程池中启动。在重写的call方法中基于Netty搭建服务端的架子来创建服务,其中事件循环组进行了连接和读写事件的分工,参数配置了最大连接数为128。

2.代理RPC泛化调用

给网关接口绑定对应的RPC服务,建立代理关系封装RPC泛化调用。这样调用网关接口就会调用到对应的RPC服务接口上并返回对应的数据。

  • 为什么要建立代理关系进行RPC的调用?调用RPC接口时如果你使用硬编码的方式,调用一个还好,如果注册到网关的RPC服务有很多呢,那你岂不是每一个RPC服务都要提供对应的调用硬编码,这样就会使代码变得冗杂,有许多实现重复逻辑的代码。这时候就离不开代理的操作了,代理将接口调用这些有共性的操作进行代理逻辑包装,这样就可以大大地减少代码量
  • 什么是RPC泛化调用?它是 RPC 接口设计中提供的一种反射调用机制,你不需要硬编码调用接口,只需要提供接口的方法名称、入参信息,即可调用到对应的 RPC 接口服务。它不需要像OpenFeign一样,调用方和服务提供方都维持一套相同的接口,只需要在调用方通过代理模式进行调用。具体可查看官方文档:使用泛化调用 | Apache Dubbo
  • 关于Cglib动态代理,由于需要对RPC服务进行代理操作,需要选择一种方式来做代理处理,而Cglib 可以满足我们自定义创建接口的方式进行代理,同时又可以再让一个代理类有多个接口。注意:多个接口的意思是,一个接口是用于标准的描述,在于使用上。另外一个接口是自主生成的,生成的是我们的 RPC 描述性接口,相当于自主生成了class字节码。

具体实现:

1.首先创建一个Configuration,会话配置类,里面暂时存储了接口信息,封装了GenericReferenceRegistry(用于将HTTP的请求方法与对应的RPC方法做关系绑定,如何实现的下面会具体讲到)。这个类就相当于ORM框架中的数据源。

2.创建GenericReferenceRegistry,用于注册代理类,将把 HTTP 的请求方法与对应的 RPC 方法做关系绑定。里面封装了一个HashMap,通过这个HashMap进行绑定,key为方法名称,value为泛化调用RPC方法的工厂类。

3.创建代理对象GenericReferenceProxy和代理对象的工厂类GenericReferenceProxyFactory。代理类采用cglib代理,实现MethodInterceptor接口,重写intercept方法,里面进行RPC泛化调用,通过调用GenericService的$invoke方法生成RPC描述性接口,用于真正的RPC调用。工厂类中封装了一个ConcurrentHashMap,key为RPC泛化调用的名字,value为自定义的IGenericReference(统一的泛化调用接口,下面会详细介绍)。通过computeIfAbsent方法遍历ConcurrentHashMap,如果存在该泛化调用代理类实例就直接返回该实例,如果不存在,则创建好后放在这个ConcurrentHashMap里面再返回。

4.定义了一个统一的泛化调用接口IGenericReference,这个接口是用于标准的描述,提供一个标准的 String 的入参和出参类型的泛化调用接口。

下面是类与接口之间的关系:

3.分治处理会话流程

通过分治重构会话流程,细化网络协议、会话、绑定、映射和泛化调用的关系

这一部分主要是重构上面写的代码,重构点包括:

  1. 拆分session包下会话业务逻辑部分和网络通信部分,做功能实现的隔离。
  2. 拆分bind包下代理和对RPC接口的泛化调用,这里你可以把RPC当做一种可连接资源,而这种连接资源也不是只有 RPC 一种,同时也因为 RPC 的泛化调用是一种通用方法,并不需要与逻辑绑定,所以它也应该被拆分出来。

  • 整个工程结构分治设计包括: bind(绑定)、mapping(映射)、session(会话)、socket(网络)这4大块。
  • 整个调用流程以 socket 网络处理协议转换后,获取会话 session 从 session 中得到映射器对象,并根据HTTP接口的 GET/POST 调用到不同的方法上。
  • 因为这样的拆分可以方便在网络层做鉴权、限流、熔断、鉴权等功能,它们可以与 session 会话逻辑拆分。这也就是本章节要拆分结构的最核心目的。
  • 另外一层关系是 bind 绑定层中,把 RPC 的泛化调用拆分出来,因为这里可以把 RPC 当成一种资源来看待,拆分后更有易于后续的池化、扩展和管理。

4.将连接(RPC\HTTP\其他)抽象为数据源

拆解Dubbo、HTTP调用,抽象为数据源服务,便于后续功能的扩展和使用

API网关的实现对于RPC接口的泛化调用,类似于ORM框架中对数据库的调用。那么我们也可以把 RPC 抽象成一种连接资源,做数据源的管理和池化的实现。这样既可以方便我们扩展新的连接方式,比如各类厂商的 RPC 框架,或者 HTTP 服务,以及你提供的大数据原始接口服务,也都可以被这样包装处理。所以这是抽象连接为数据源的设计目的。

整个InfiniGate网关的通信模型结构已经逐步的清晰,从网络协议转换->开启通信会话->获取映射关系->执行具体的请求方案,到现在要实现的抽象的数据源。把 RPC、HTTP 当做数据源来维护。

数据源服务核心链关系:

具体实现方案:

1.新建一个包datasource,用于抽象数据源调用。在包下创建接口Connection,用于建立连接。创建connection包,里面包含了DubboConnection和HTTPConnection对象实现Connection接口,用于发送RPC或者HTTP请求,这些是不同策略实现的连接类。

2.创建DataSource接口,用于获取连接资源。创建DataSourceFactory接口,用于创建数据源连接池的对象。创建unpooled包,包下创建UnpooledDataSource对象和其工厂对象UnpooledDataSourceFactory分别实现DataSource、DataSourceFactory接口。上面已经有了不同策略实现的连接类,这里就对这些连接的使用进行一个统一的数据源管理,同时将来还可以基于这样的连接信息做池化(限制连接数量,连接的重用)的处理,提供使用效率。

3.会话使用数据源。在网关会话中需要对数据源进行创建使用,在 DefaultGatewaySessionFactory 工厂中构建数据源,在 DefaultGatewaySession 使用数据源。

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

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

相关文章

吃透2000-2024年600道真题和解析,科学高效通过2025年AMC8竞赛

为帮助孩子科学、有效备考AMC8竞赛&#xff0c;我整理了2000-2004年的全部AMC8真题&#xff08;完整版共600道&#xff0c;且修正了官方发布的原试卷中的少量bug&#xff09;&#xff0c;并且独家制作成多种在线练习&#xff0c;利用碎片化时间&#xff0c;8个多月的时间足以通…

【Redis 神秘大陆】008 常见Java客户端

八、Redis 的 Java 客户端 8.1 Jedis 连接池 单点连接池 Jedis 连接池基于 Common-Pool 连接池里面放置的是空闲连接&#xff0c;如果被使用 &#xff08;borrow&#xff09;掉&#xff0c;连接池就会少一个连接&#xff0c;连接使用完后进行放回 &#xff08;return&#…

HCIA-Datacom实验_05_实验三:OSPF路由协议基础实验

一、实验拓扑 二、实验步骤 (一)修改设备名称、配置接口IP、Loopback口IP R1 R2 R3 (二)配置OSPF R1 R2 R3 (三)配置认证 R1 R2 R3

【学习笔记八】EWM仓库流程类型的后台配置和前台测试

一、仓库流程类型概述 仓库流程类型&#xff08;Warehouse Process Types&#xff09;&#xff0c;简称WPT 在SAP扩展仓库管理(SAPEWM)中&#xff0c;WPT控制仓库内每个流程的活动或移动&#xff08;如收货、发货、过帐更改&#xff09;。仓库流程类型被分配给每个仓库请求项目…

【机器学习】贝叶斯算法在机器学习中的应用与实例分析

贝叶斯算法在机器学习中的应用与实例分析 一、贝叶斯算法原理及重要性二、朴素贝叶斯分类器的实现三、贝叶斯网络在自然语言处理中的应用四、总结与展望 在人工智能的浪潮中&#xff0c;机器学习以其独特的魅力引领着科技领域的创新。其中&#xff0c;贝叶斯算法以其概率推理的…

1、MYSQL系列-深入理解Mysql索引底层数据结构与算法

索引的本质 索引是帮助MySQL高效获取数据的排好序的数据结构 索引数据结构 二叉树红黑树Hash表BTree B-Tree B-Tree 叶节点具有相同的深度&#xff0c;叶节点的指针为空&#xff0c;所有索引元素不重复&#xff0c;节点中的数据索引从左到右递增排列 BTree(B-Tree变种) 非叶…

DataGrip2024安装包(亲测可用)

目录 一、软件简介 二、软件下载 一、软件简介 DataGrip是由JetBrains公司开发的一款强大的关系数据库集成开发环境&#xff08;IDE&#xff09;&#xff0c;专为数据库开发人员和数据库管理员设计。它提供了一个统一的界面&#xff0c;用于管理和开发各种关系型数据库&#x…

Linux内核之WRITE_ONCE用法实例(四十八)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

stm32实现hid键盘

前面的cubelmx项目配置参考 stm32实现hid鼠标-CSDN博客https://blog.csdn.net/anlog/article/details/137814494?spm1001.2014.3001.5502两个项目的配置完全相同。 代码 引用 键盘代码&#xff1a; 替换hid设备描述符 先屏蔽鼠标设备描述符 替换为键盘设备描述符 修改宏定…

深度学习 Lecture 7 迁移学习、精确率、召回率和F1评分

一、迁移学习&#xff08;Transfer learning) 用来自不同任务的数据来帮助我解决当前任务。 场景&#xff1a;比如现在我想要识别从0到9度手写数字&#xff0c;但是我没有那么多手写数字的带标签数据。我可以找到一个很大的数据集&#xff0c;比如有一百万张图片的猫、狗、汽…

基于Adaboost模型的数据预测和分类matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 AdaBoost&#xff08;Adaptive Boosting&#xff09;是一种集成学习方法&#xff0c;由Yoav Freund和Robert Schapire于1995年提出&#xff0c;主要用于提高弱分类…

UML 介绍

前言 UML 简介。 文章目录 前言一、简介1、事务2、关系1&#xff09;依赖2&#xff09;关联聚合组合 3&#xff09;泛化4&#xff09;实现 二、类图三、对象图四、用例图五、交互图1、序列图&#xff08;顺序图&#xff09;2、通信图 六、状态图七、活动图八、构件图&#xff0…

详解UART通信协议以及FPGA实现

文章目录 一、UART概述二、UART协议帧格式2.1 波特率2.2 奇校验ODD2.3 偶校验EVEN 三、UART接收器设计3.1 接收时序图3.2 Verilog代码3.3 仿真文件测试3.4 仿真结果3.5 上版测试 四、UART发送器设计4.1 发送时序图4.2 Verilog代码4.3 仿真文件测试4.4 仿真结果4.5 上板测试 五、…

HarmonyOS开发实战:【亲子拼图游戏】

概述 本篇Codelab是基于TS扩展的声明式开发范式编程语言编写的一个分布式益智拼图游戏&#xff0c;可以两台设备同时开启一局拼图游戏&#xff0c;每次点击九宫格内的图片&#xff0c;都会同步更新两台设备的图片位置。效果图如下&#xff1a; 说明&#xff1a; 本示例涉及使…

2016NOIP普及组真题 1. 金币

线上OJ&#xff1a; 一本通&#xff1a;http://ybt.ssoier.cn:8088/problem_show.php?pid1969 核心思想&#xff1a; 解法1、由于数据量只有 10000 天&#xff0c;估可以采用 模拟每一天 的方式。 #include <bits/stdc.h> using namespace std;int k 0;int main() {i…

SpringBoot项目基于java的教学辅助平台

采用技术 SpringBoot项目基于java的教学辅助平台的设计与实现~ 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBootMyBatis 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 页面展示效果 学生信息管理 教师信息管理 课程信息管理 科目分类管…

【面试经典 150 | 链表】K 个一组翻转链表

文章目录 写在前面Tag题目来源解题思路方法一&#xff1a;迭代 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于本题涉及到的数据结构等内容进行回顾…

xxl-job使用自动注册节点,ip不对,如何解决????

很明显这时我们本机的ip和我们xxl-job自动注册的ip是不一致的&#xff0c;此时该如何处理呢&#xff1f;&#xff1f;&#xff1f;&#xff1f; 方法一&#xff1a;在配置文件中&#xff0c;将我们的ip固定写好。 ### xxl-job executor server-info xxl.job.executor.ip写你的…

pandas基本用法

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、pandas的数据结构1、一维数组pd.Series1.1 pd.Series&#xff08;data,index,dtype&#xff09;示例1&#xff1a;不定义index示例2&#xff1a;自定义inde…

基于HMM隐马尔可夫模型的金融数据预测算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于HMM隐马尔可夫模型的金融数据预测算法.程序实现HMM模型的训练&#xff0c;使用训练后的模型进行预测。 2.测试软件版本以及运行结果展示 MATLAB2022A版本运…