【自研网关系列】网关的技术选型以及架构设计

🌈Yu-Gateway:基于 Netty 与原生 Java 实现,使用 Nacos 作为注册与配置中心。项目实现多种过滤器,包含路由、负载均衡、鉴权、灰度发布等过滤器。

🌈项目代码地址:GitHub - YYYUUU42/YuGateway-master

如果该项目对你有帮助,可以在 github 上点个 ⭐ 喔 🥰🥰

🌈自研网关系列:可以点开专栏,参看完整的文档

目录

1、市场调研        

2、技术选型

性能与可伸缩性

安全性

可观测性

路由能力/高可用

多协议支持

总结

3、技术架构

4、网关处理流程


1、市场调研        

        在设计一个项目之前,进行全面的市场调研与竞品分析是不可或缺的环节。这一步骤旨在深入了解当前市场上已有的同类产品,明确它们的优势与不足,然后提炼出设计这个项目的一个设计方向。

所以调查了市面上已有的且比较知名的网关项目,列举出了如下这张优缺点以及侧重点的表格。

Gateway名称

优点

缺点

设计侧重点

Spring Cloud Gateway

基于 Spring 框架,拥有庞大的 Spring 生态系统,可以轻松集成其他组件

相对于其他选择,性能较慢。其生态和社区支持较弱

集成多种协议和插件,扩展性

Nginx

高性能,配置灵活,轻量级,高稳定性

模块化程度低,扩展性差,异步处理能力受限

高性能HTTP服务器和反向代理

Apache HTTP Server

模块丰富,社区活跃,跨平台,文档齐全

性能较差,配置复杂,更重量级

多功能Web服务器,重视模块化

HAProxy

高性能,支持TCP和HTTP代理,稳定且成熟

配置不如Nginx直观,缺乏现代Web界面

专注于高并发连接的负载均衡

Traefik

自动化服务发现和配置,容器和微服务友好,易于部署

社区较新,历史较短

云原生环境中的动态配置

Kong

基于Nginx和OpenResty,提供丰富的插件,管理界面友好

高性能场景可能需优化配置,插件生态不如Apache/Nginx

扩展性和插件生态系统

基于上面这些比较成熟且知名度较高的网关,提炼出了设计一个网关的侧重点:

1、性能与可伸缩性:

  • 关注高吞吐量和低延迟处理,以便能够处理大量并发连接和数据流。
  • 设计可在多个服务器、数据中心或地理区域之间伸缩的解决方案。

2、安全性:

  • 实现高级安全特性,如SSL/TLS终止、OAuth、JWT、API密钥验证和防止DDoS攻击等。
  • 确保所有通过网关的流量都符合最新的安全标准和法规要求。

3、可观测性:

  • 提供详细的监控和日志记录功能,使运维团队能够观测和诊断问题。
  • 集成与现有监控工具和警报系统的能力。

4、路由能力:

  • 开发动态路由和负载均衡策略,以支持微服务架构中服务发现的需求。
  • 支持基于URL、路径或头部的路由决策。

5、扩展性:

  • 构建插件架构,使新功能能够以模块化的方式添加。
  • 保持核心轻量级,允许通过插件或服务集成额外功能。

6、多协议支持:

  • 考虑支持多种网络协议,不仅限于HTTP/HTTPS,也包括WebSocket、RPC等。

7、高可用性:

  • 确保网关设计能够容忍单点故障和网络分区,提供故障转移和灾难恢复机制。

基于上面列举出来的这些点之后,就可以开始分析,应该如何从这些点入手将一个具体的问题拆解为几个细粒度的解决方法。

接下来一点一点的对上面的七个点进行分析,分析其具体的解决方法和思路。

于是就有了如下的答案:

1、性能与可伸缩性:

  • 使用 Netty 进行异步网络编程,Netty 是一个高性能的网络应用程序框架,可以处理大量的并发连接。
  • 缓存 如 Caffeine 或 Redis 来减少数据库访问频率,提升性能。

2、安全性:

  • 集成 JWT 用于安全的API访问。
  • 利用 TLS/SSL 加密传输数据。

3、可观测性:

  • 集成 MicrometerDropwizard Metrics 来收集和导出性能指标。
  • 使用 ELK Stack(Elasticsearch, Logstash, Kibana)来收集和分析日志数据。
  • 利用 PrometheusGrafana 进行监控和警报。

4、路由能力:

  • 利用 Zuul 或自定义的 Servlet Filters 进行动态路由。
  • 结合 ConsulEureka Nacos 进行服务发现和注册。

5、扩展性:

  • 设计插件架构,使得可以通过 Java SPI (Service Provider Interface) 加载新模块。

6、多协议支持:

  • 使用 gRPC/Dubbo 来支持RPC调用。
  • 支持 WebSocket 用于双向通信,使用Java的 JSR 356Spring Framework 的WebSocket API。

7、高可用性:

  • 使用 Nacos / ZooKeeper / etcd 来管理网关的配置信息和服务元数据,以支持高可用部署。

好的,那么其实基于上面的分析,就已经可以大致的得到设计一个网关所需要的一些技术上的方向了,接下来的就是确定这些技术,并且确定自己设计该网关时的一个架构图了。

2、技术选型

性能与可伸缩性

参考目前主流的网关的设计,有 SpringCloud Gateway 以及 Zuul,他们的底层都大量使用了异步编程的思想,并且也都有非常重要的网络通信上的设计。

由于我们的网关是自研的,也就是他自己本身就是一个单独的服务,因此我们并不需要使用到SpringBoot这种框架,我们可以直接使用原生Java框架来编写各种重要代码。且 Spring Cloud Gateway 底层也是大量使用到 Netty,所以网络通信上也还是使用 Netty 即可。

缓存以及高性能这方面,分布式缓存我们使用 Redis,本地缓存选择 Caffeine,因为 Redis 是市面上使用最广泛的缓存中间件,而 Caffeine 更是有着本地缓存之王的称号,所以选择这两个主要是看中了其成熟的特点。

然后为了提高其缓存区的性能,这里考虑使用 Disruptor 这个无锁队列,因为其无界队列的特性,可以将其作为缓存区队列提高性能。

安全性

使用JWT,其优点在于简单的Token格式,便于跨语言和服务传递,适合于微服务和分布式系统的安全性设计。

当然缺点也在于我们需要精细的管理和保护我们的密钥。

这里我并不打算支持TLS/SSL,首先是我作为个人开发者,想要去支持TLS/SSL是比较复杂的,并且我还需要管理证书的生命周期,会影响项目开发的进度,因此我并不打算在我的网关中支持TLS/SSL。

可观测性

MicrometerDropwizard Metrics:

  • 优点: 两者都是成熟的度量收集框架,提供了丰富的度量集合和报告功能。
  • 缺点: 可能需要适配特定的监控系统或标准。

ELK Stack:

  • 优点: 提供了一个完整的日志分析解决方案,适用于大规模日志数据的收集、搜索和可视化。
  • 缺点: 组件较多,搭建和维护相对复杂。

PrometheusGrafana:

  • 优点: 高度适合于时序数据监控,Grafana 提供强大的数据可视化。
  • 缺点: 需要配置和维护 Prometheus 数据抓取和存储。

这里我选择使用最后一种,因为目前市面上这种用的比较多,并且Prometheus相对于其他的更加简单易用。

路由能力/高可用

同时,在上文也提到了,网关是需要用到注册中心的,因为我们的请求具体最后要转发到那个路由,是需要从注册中心中拉取服务信息的,目前注册中心有:Zookeeper,Eureka,Nacos,Apollo,etcd,Consul

他们各有优劣势,比如Zk保证的是CP而不是AP,我们知道,网关是应用的第一道门户,我们使用 Dubbo 的时候会使用 Zk ,但是对于网关,可用性大于一致性,因此 Zk 我们不选。

而 Eureka 都和 Spring Cloud 生态有比较紧密的联系,因此如果我们使用它,就会增加我们的网关和 Spring Cloud 的耦合,不太符合我们自研的初衷,所以也不选。

Etcd 虽然是通用的键值对分布式存储系统,可以很好的应用于分布式系统,但是依旧没有很好的优势,当然,他很轻量级。所以这里暂不考虑。

Consul 和 Etcd 差不多,所以这里也不考虑 Consul。

这里我选用 Nacos 作为注册中心,Nacos 首先支持 CP 和 AP 协议,并且提供了很好的控制台方便我对服务进行管理。同时,Nacos 的社区相对来说非常活跃,网络上的资料也更加的多,同时,我也看过 Nacos 的源码,编写优雅且相对易懂。同时我相信会使用 Nacos 的人肯定更多,因此在这里选择 Nacos 作为注册中心。

当然,上面的几种注册中心都可以使用,没有特别明显的优劣势,他们也都有各自合适的场合,具体场合具体分析,主要是要分析自己的团队更加了解或者适合哪一种注册中心。

而配置中心方面,有SpringCloud Config,Apollo,Nacos。

这里很明显,依旧选择 Nacos,因为 Nacos 不仅仅是注册中心也是配置中心。因此选用 Nacos 我们可以减少引入不必要的第三方组件。

多协议支持

可以考虑的有 gRPC 和 Dubbo ,gRPC 支持多种语言,并且基于HTTP/2.0,Dubbo在 Alibaba 使用的比较多,并且比较适合 Java 的生态。同时 gRPC 的使用要求熟悉Protobuf,所以这里为了减少成本,考虑使用Dubbo。

总结

所以,经过一套分析,我们就可以得出如下的主要技术栈:

  1. 开发语言:Java 19
  2. 网络通信框架:Netty 4.1.51
  3. 缓存:Redis、Caffeine 版本不限
  4. 注册中心与配置中心:Naccos 2.0.4
  5. RPC协议:Dubbo 2.7.x
  6. 日志监控:Prometheus、Grafana 版本不限
  7. 安全鉴权:JWT 版本不限

3、技术架构

Common:维护公共代码,比如枚举

Client:客户端模块,方便我们其他模块接入网关

Register Center:注册中心模块

Config Center:配置中心模块

Container:包含核心功能

Context:请求上下文,规则

FilterChain:通过责任链模式,链式执行过滤器

FlowFilter:流控过滤器

LoadBalanceFilter:负载均衡过滤器

RouterFilter:路由过滤器

TimeoutFilter:超时过滤器

OtherFilter:其他过滤器

NettyHttpServer:接收外部请求并在内部进行流转

Processor:后台请求处理

Flusher:性能优化

MPMC:性能优化

SPI Loader:扩展加载器

Plugin Loader:插件加载器

Dynamic Loader:动态配置加载器

Config Loader:静态配置加载器

4、网关处理流程

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Linux】进程间通信——system V版本 共享内存

目录 共享内存 原理 实践 shmget() 创建共享内存 shmctl() 删除共享内存 shmat() 挂接进程和共享内存 shmt() 进程和共享内存去关联 共享内存的特性 优势 劣势 用共享内存实现进程间通信 共享内存 原理 两个进程的PCB各自维护着一个进程地址空间。当两个进…

Linux的学习之路:8、Linux调试器-gdb使用

摘要 本章主要是说一下gdb的使用,以及把使用指令放入放个指令手册。 目录 摘要 一、背景 二、使用 1、产生debug文件 2、进入gdb 3、使用指令 三、思维导图 一、背景 Linux调试器gdb的背景主要涉及到Linux程序发布方式和调试需求。 在Linux中&#xff0c…

SpringBoot学习笔记二

SpringBoot学习笔记二 1.SpringBoot配置加载顺序1.1 内部配置加载顺序1.2 外部配置加载顺序 2. SpringBoot整合其他框架2.1 SpringBoot整合Test2.2 SpringBoot整合Redis 1.SpringBoot配置加载顺序 1.1 内部配置加载顺序 同理可知,父项目中的confg下的配置优先级最…

探索Java中的栈:Stack与Deque(ArrayDeque和LinkedList)

文章目录 1. 栈(Stack)1.1 定义方式1.2 特点1.3 栈的层次结构 2. 双端队列(Deque)2.1 定义方式及继承关系2.2 特点:2.3 ArrayDeque2.4 LinkedList2.5 Deque 的各种方法2.6 如何选择ArrayDeque和LinkedList 3. 如何选择…

【稳定检索|投稿优惠】2024年生物学与智能计算国际会议 (ICBIC 2024)

2024年生物学与智能计算国际会议 (ICBIC 2024) 2024 International Conference on Biology and Intelligent Computing 【会议简介】 2024年生物学与智能计算国际会议即将在上海召开。本次会议旨在汇聚生物学与智能计算领域的专家学者,共同探讨两者交叉融合的前沿…

【Linux】网络基础(一)

文章目录 一、计算机网络背景1. 网络发展2. 认识“协议” 二、网络协议初识1. 协议分层2. OSI七层模型3. TCP/IP五层(或四层)模型 三、网络传输基本流程1. 同局域网的两台主机通信数据包封装和分用封装分用 2. 跨网络的两台主机通信 四、网络中的地址管理…

【webrtc】源码下载与编译

目录 下载 下依赖 内存需求 !! 参考文章 : 下载 (1) windows ,centos上都会报错 (2) ubuntu A : 在git上设置代理 B fetch通过 ubuntu的界面 proxy设置了代理 这将会拉取webRTC源码,且额外加了a…

ssm043基于JavaEE的龙腾公司员工信息管理系统的设计与实现+jsp

龙腾公司员工信息管理系统设计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本龙腾公司员工信息管理系统就是在这样的大环境下诞生,其可…

C++数据结构与算法——动态规划打家劫舍系列

C第二阶段——数据结构和算法,之前学过一点点数据结构,当时是基于Python来学习的,现在基于C查漏补缺,尤其是树的部分。这一部分计划一个月,主要利用代码随想录来学习,刷题使用力扣网站,不定时更…

千视电子携NDI 6前沿技术,亮相北京CCBN展呈现轻量化媒体解决方案

千视携NDI 6技术闪耀2024 CCBN展会,呈现轻量化媒体解决方案 2024年4月24日至26日,北京首钢会展中心将举办第三十届中国国际广播电视网络技术展览会(CCBN2024)。这是中国广播电视行业的一项重要盛会,将有国内外超600家…

kubectl_入门_Pod配置以及生命周期

Pod配置以及生命周期 1. Pod结构定义 每个pod中都可以包含一个或多个容器,这些容器可以分为两类 用户程序所在的容器,数量可多可少Pause容器,这是每个Pod都会有的一个根容器,它的作用有两个 可以以它为根据,评估整个…

异地两分部子网重复,如何远程更改其中一个分部子网信息

环境: 分部1:子网192.168.1.0/24 分部2:子网192.168.1.0/24 问题描述: 异地两分部子网重复,如何远程更改其中一个分部子网,原本没有问题目前要与总部建ipsec提示冲突无法都建立隧道 解决方案: 先G一下,看看有啥建议 在两个异地分部网络中,如果发现有子网地址出现…

mac上如何安装python3

mac上如何安装python3? 安装homebrew 在终端执行命令 /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 执行完成后,homebrew和pip等工具就自动安装好了。 接下来安装python3.在终端…

鸿蒙OS开发实例:【Native C++】

介绍 本篇Codelab主要介绍如何使用DevEco Studio创建一个Native C应用。应用采用Native C模板,实现使用NAPI调用C标准库的功能。使用C标准库hypot接口计算两个给定数平方和的平方根。在输入框中输入两个数字,点击计算结果按钮显示计算后的数值。 相关概…

lanqiao.602 迷宫

题目&#xff1a; 代码&#xff1a; #include<iostream> #include<cstring> #include<algorithm> #include<queue> using namespace std; char mp[31][51]; //稍微开大一点 char k[4]{D,L,R,U}; //按字典序记录路径 int dirx[]{1,0,0,-1},d…

学习ArkTS -- 常用组件使用

学习ArkTS 使用Deveco studio写ArkTSImage: 图片显示组件1.声明Image组件并设置图片源2. 添加图片属性 Text: 文本显示组件1. 声明Text组件并设置文本内容2. 添加文本属性 TextInput&#xff1a;文本输入框1. 声明TextInput2. 添加属性和事件 Button 组件1. 声明Button组件&…

关于“使用java中的二维矩阵方法生成二维码“ 以及 “Java加载外部字体文件时出错的原因“

生成二维码 铁铁们,这两日写了一个导出二维码的接口,要求有一个是在二维码下方生成字体,现在奉上生成二维码的代码: controller层 Operation(summary "导出机构二维码",description "导出机构二维码")GetMapping("/orgCode")public void getO…

Java-Doc

Java-Doc javdoc命令是用来生成自己的API文档的 参数信息&#xff1a;author作者名version版本号since知名需要最早使用的jdk版本param参数名return返回值情况throws异常抛出情况 1.参数信息的使用&#xff1a; 未完待续... ...

HashMap部分底层源码解析

哈希表的物理结构 HashMap底层都是哈希表&#xff08;也称散列表&#xff09;&#xff0c;线程不安全&#xff0c;其中维护了一个长度为2的幂次方的Entry类型的数组table&#xff0c;数组的每一个索引位置被称为一个桶(bucket)&#xff0c;你添加的映射关系(key,value)最终都被…

腾讯云向量数据库-RAG介绍

1.说明 RAG结合LLM(通用大预言模型)构件基于私有文档、专业领域知识、实时信息的charbot。 2.RAG的主要步骤 知识切片成chunk向量化chunk入库query检索知识chunk构件prompts调用llm生成回答 3.优势 快速构件demo快速理解rag社区支持 4.痛点 投入大效果差调优难 5.RAG应…