Apache shenyu,Java 微服务网关的首选

2023-09-19 09:56:13

微服务网关的产生背景

当我们系统复杂度越来越高,团队协作效率越来越低时,我们通常会想到通过"拆分"来应对,这是典型的"化繁为简,分而治之"的思想。在落地过程中,我们通常会引入"SOA"或者"微服务"架构手段,如下图所示:
image.png

技术更新日新月异,站在当下去看,“微服务”、“API网关”、“云原生”、“service mesh”…这些早已不是什么新鲜概念。但只有完整经历过架构演进,才能倒出其中缘由,因为架构演进并非一蹴而就的。

时光回到2014年,很多公司在忙着对遗留系统做"前后端分离"和"服务化拆分",不管是追潮流,还是真解决问题,反正很多公司都在这么干。架构大概是这个样子的:
image.png
简单描述一下,这里的Web Server通常是我们熟悉的Nginx,它承担了2个职责。第一,作为反向代理和七层负载均衡器,负责将浏览器或者APP端的请求转发到指定的后端服务中。第二,它也作为前端静态站的Web容器。
这个架构有很多问题,典型的问题如下:

  1. 端上直接请求后端服务,强耦合,如果后端服务做字段修改了很可能会影响到端上
  2. 客户端需要多次请求服务,完成一个页面的渲染
  3. 很多通用的逻辑没有收敛,比如:用户身份验证,所以你可能在服务上面看到各种Filter、切面

为了解决上面这些问题,所以很多公司又引入了一个中间层。这也再次印证了那句话–在计算机系统的世界里,没有问题是不能通过引入"第三者"解决的。架构如下:
image.png

这一层中间层,用现在流行的叫法叫做"BFF"。有些公司可能会是前端同学通过Node.js来实现,也有些是后端同学来实现的。当然,由于我主导的很多系统都经历过单体(前后端不分离)、前后端分离、网站应用垂直拆分、无线化、开放平台、SOA服务化(服务下沉)等演进历程。在SOA改造的过程中,本质上我们是通过服务下沉的方式,把一些共享的能力做接口抽象和复用,自然也有保留一套或者多套比较薄的Web应用做中间层,去接收前端和APP端的请求,做一些字段裁剪、接口响应内容的拼接等等。所以,我并没有踩过上面的坑。因为每一步演进都是为了解决真问题,所以也很自然。那个时候我没有关注什么"微服务"、"BFF"之类的概念,只不过解法和套路都是类似的。

但是呢。因为团队越来越大,业务越来越多,这种"中间层"应用也越来越多,大概成了这个样子:
image.png

在这些中间层应用里面,同样还是存在一些重复的逻辑没有收敛,典型的如下:

  1. 请求身份验证,鉴权等
  2. 切面的日志打印,QPS和耗时统计等
  3. 请求的限流、熔断等

既然要解决这些问题,把一些非业务属性且公共的逻辑剥离出来,那很自然的会想到"在BFF的前面再加一层"。这也就是我们今天要介绍的"API网关",或者叫"微服务网关"。
image.png
当然,这个图里面省去了最前面的DNS/CDN/GSLB,LVS/HAProxy/Nginx等网络接入和负载均衡等细节。
简单总结一下网关的职责:

  • 请求流量的路由转发、负载均衡
  • 安全验证(身份认证、请求鉴权等)
  • 限流、熔断
  • 日志、指标度量等
  • 协议适配
  • 请求缓存

微服务网关的生态

Java社区的微服务网关

在很长的一段时间里,Java社区的微服务网关主要由Spring Cloud生态来提供,所以选择也不多。
image.png

这两者,可以满足一般中小型公司的业务场景和需求,但是他们存在一些共同的问题:

  1. 缺少动态配置和动态更新能力,需要整合配置中心做二次开发
  2. 缺少可视化的操作和维护界面。无论是从体验还是从效率的角度来看,可视化都非常重要
  3. 缺少限流、降级,日志、监控等完整的方案,需要各种整合和二次开发
  4. 缺少协议转换的能力,后端服务如果是直接通过RPC协议暴露的则无法被前端访问

Nginx/OpenResty体系的网关

Nginx算是网关吗?回答这个问题之前我们先仔细想想,Nginx的职责和功能和我们上面说的网关好像是有一些重叠的。例如:请求转发、负载均衡、限流(借助模块)、安全认证等等。基于Nginx/Openresty生态衍生出来的,比较具有代表意义的主要有老牌的Kong,以及近两年比较火的APISIX这两款。详细对比如下:
image.png

从广义上来讲,Nginx/Openresty也是网关,这个并没有权威的定义。通常,我们可以把网关又细分为:
流量网关,顾名思义就是控制流量进入集群的网关。
业务网关,更加贴合业务服务的,也就是我们说的微服务网关。
当然,这两者并没有绝对的界限。所以,通常我们在实际应用场景中都是搭配使用的。

云原生网关

进入云原生时代之后,Kubernetes已经成为了云原生应用底座的事实标准。而我们要想应用暴露给外部访问,首先绕不开的就是Ingress 控制器。image.png
上面这张图比较老,大概是2021年前后的。Ingress和云原生API GATEWAY这个市场的玩家特别多,还包括Service Mesh数据面事实标准Envoy推出的Envoy Gateway**,**最近比较火的阿里云基于Envoy改造的Higress,以及淘系基于Tengine改造的Tengine-Ingress等等。
image.png

为什么推荐你直接使用Apache shenyu

Apache shenyu的特性包含:

  • 请求代理:支持Apache Dubbo,Spring Cloud,gRPC,Motan,SOFA,TARS,WebSocket,MQTT等协议的转换
  • 安全性:签名,OAuth 2.0,JWT插件,WAF插件
  • API治理:请求、响应、参数映射、限流熔断、流量灰度、接口文档
  • 可观测性:跟踪、指标、日志记录插件
  • 仪表板:动态流量控制,可视化操作
  • 高性能:基于Netty,纯异步非阻塞模式
  • 高扩展:插件机制,热插拔,SPI按需动态加载
  • 热更新:数据实时同步,无需重启集群
  • 集群:NGINX、Docker、Kubernetes
  • 语言:提供.NET,Python,Go,Java客户端用于API注册
  • 开箱即用:功能丰富稳定,开箱即用,简单添加引用就能接入,几乎没有业务侵入性和接入成本
  • 生态友好:目前已集成常见的中间件,包括服务框架、限流熔断、服务发现、配置中心等。目前也在积极拥抱云原生
  • 社区活跃:Apache顶级项目,目前社区有来自全球贡献者超过300名,github star超过8K,据观察几乎每天都有代码提交更新和PR合并动作。社区活跃程度**是选择开源软件的首要考虑项 **

更多信息,请参考Apache shenyu网站和github主页:
https://github.com/apache/shenyu** ,**https://shenyu.apache.org/zh/docs/index

如果你们公司系统是Java体系的,对功能、性能、扩展性等方面又比较有追求,但又没有自研能力和时间,那我推荐你直接使用Apache shenyu 来做微服务网关,几乎满足绝大部分公司对网关的诉求。

为什么我不推荐你单独使用云原生网关?

这些云原生网关确实都很优秀,有很多吸引人的特性,甚至时不时有"取代传统微服务网关"的声音。但是,优秀的未必就适合你,简单总结有如下原因:

  1. 云原生已经普及了好几年,大部分公司的应用系统也都逐渐跑在了Kubernetes之上。但是,大部分公司的应用还是基于Dubbo/Spring Cloud + ZK/Nacos/Consul这种传统的微服务架构,并非天生就是基于Kubernetes的Service体系构建的,也不是直接基于Service Mesh体系来构建的。所以,云原生网关目前对你来说还是属于那种看起来或者听起来很美好,独立使用又发挥不出它的全部价值来。
  2. 这些网关普遍对Java开发人员并不友好。比如,Nginx和Openresty体系,很多时候借助Nginx模块(C代码)和Lua脚本来实现扩展的,这对使用者来说是有一定门槛的。Envoy体系是基于C++来实现的。当然,为了解决这些痛点问题,最新的这些云原生网关厂商也在积极拥抱WASM生态,试图降低开发者扩展的门槛,不过WASM目前对Java的支持并不友好。所以,无论是想开发插件扩展,还是想进行深度的二次开发定制,门槛都不低,这也会让你十分难受。
  3. 太新的技术,生态可能还不够完善,各方面成熟度还有待验证,不推荐轻易在生产直接使用
  4. 取代微服务网关,这有点言之过早。目前我更推荐搭配使用,各司其职。10多年前Nginx流行的时候很多人绝对LVS要完了,但到现在IPVS也还在内核中。Spring Cloud刚开源的时候业内很多人也在唱衰Dubbo,Service Mesh出现的时候也被认为是颠覆性的二代微服务架构。

总结

本文先从微服务网关的诞生背景出发,带读者重新温习了一下近些年互联网公司中普遍的架构演进的过程。然后重点介绍了传统的微服务网关,传统的流量网关,以及面向云原生的Ingress控制器和API网关。
最后,重点介绍了一下Apache shenyu的特性,以及为什么我不推荐你单独使用那些云原生网关。当然,水平有限,也纯属一家之言,也欢迎读者在留言区交流和留言讨论。

更多推荐

Web安全与攻防

Web安全概述在Internet大众化及Web技术飞速演变的今天,在线安全所面临的挑战日益严峻。伴随着在线信息和服务的可用性的提升,以及基于Web的攻击和破坏的增长,安全风险达到了前所未有的高度。Web安全可以从以下三个方面进行考虑:Web服务器的安全、Web客户端的安全、Web通信信道的安全。针对Web服务器的攻击可

从HTTP到HTTPS:网站安全通信的演进之路

HTTP协议与TCP/IP协议族内的其他协议相同部分,用于客户端和服务器端的通信。下面来看一下HTTP具体是怎么工作的。1、HTTP前生今世在HHTP/0.9版本,主要是通过确立了客户端请求、服务器端响应的通信流程来解决HTML文件传输,只能获取文本资源。HTTP/1.0是一个简单的文本协议,通过设立头部字段来解决不同

5.2 磁盘CRC32完整性检测

CRC校验技术是用于检测数据传输或存储过程中是否出现了错误的一种方法,校验算法可以通过计算应用与数据的循环冗余校验(CRC)检验值来检测任何数据损坏。通过运用本校验技术我们可以实现对特定内存区域以及磁盘文件进行完整性检测,并以此来判定特定程序内存是否发生了变化,如果发生变化则拒绝执行,通过此种方法来保护内存或磁盘文件不

二十一、MySQL(多表)内连接、外连接、自连接实现

1、多表查询(1)基础概念:(2)多表查询的分类:2、内连接(1)基础概念:(2)隐式内连接:基础语法:select表1.name,表2.namefrom表1,表2where表1.外键=表2.被链接的字段;实际操作:#(1)查询每一个员工的姓名,以及关联的部门名称--隐式查询selectemp.name,course.

gulp 错误集锦

为了打包构建之前的layui写的项目,用到了gulp,但是遇到的坑还挺多,记录一下。1、运行gulp时报错ReferenceError:primordialsisnotdefined解决办法:ReferenceError:primordialsisnotdefined意思是primordials这个没被定义,是因为项目

Centos配置链路聚合bond的步骤

Centos配置链路聚合的步骤如下:查看网卡名称和状态Shell#nmclidevicestatus创建bond0网卡Shell#vi/etc/sysconfig/network-scripts/ifcfg-bond0DEVICE=bond0ONBOOT=yesBOOTPROTO=noneNM_CONTROLLED=n

prometheus+node+process-exporter+grafans

安装Prometheus要在Ubuntu18.04上安装Prometheus,您可以按照以下步骤进行:sudoapt-getupdate安装依赖:sudoapt-getinstallwgettar下载最新的Prometheus版本:wgethttps://github.com/prometheus/prometheus

第34章_瑞萨MCU零基础入门系列教程之SR04超声波测距实验

本教程基于韦东山百问网出的DShanMCU-RA6M5开发板进行编写,需要的同学可以在这里获取:https://item.taobao.com/item.htm?id=728461040949配套资料获取:https://renesas-docs.100ask.net瑞萨MCU零基础入门系列教程汇总:https://b

【Java 基础篇】Java类型通配符:解密泛型的神秘面纱

在Java中,类型通配符(TypeWildcard)是泛型的重要概念之一。它使得我们能够更加灵活地处理泛型类型,使代码更通用且可复用。本文将深入探讨Java类型通配符的用法、语法和最佳实践。什么是类型通配符?类型通配符是一个用问号?表示的通配符,它可以用于泛型类、方法和通配符边界。类型通配符的主要作用是让我们能够接受各

OpenCV之cvtColor颜色空间转换

大多数彩色图片都是RGB类型,但是在进行图像处理时,需要用到灰度图、二值图、HSV、HSI等颜色制式,opencv提供了cvtColor()函数来实现这些功能。首先看一下cvtColor函数定义:C++:voidcvtColor(InputArraysrc,OutputArraydst,intcode,intdstCn

PyTorch深度学习(一)【线性模型、梯度下降、随机梯度下降】

这个系列是实战(刘二大人讲的pytorch)建议把代码copy下来放在编译器查看(因为很多备注在注释里面)线性模型(LinearModel):importnumpyasnpimportmatplotlib.pyplotasplt#绘图的包​x_data=[1.0,2.0,3.0]#这两行代表数据集,一般x_data,y

热文推荐