前言
一般常规的项目立项之初会有一份 MRD(Market Requirements Document,市场需求文档)用来判断产品的必需性以及价值等。
对于基础项目开发来说,使用 MRD 可能有些重量级,但我们也需要对一个新的基建类型项目做一个简单评估,包括研发必需性、投入的成本以及产生的价值等等。有些轮子是必造,而有些轮子不是。
这一章,我们就来探讨一下:你的团队需要一个网关系统吗?
应用场景
对于现在主流的后端架构来说,微服务的普及范围还是比较广的,毕竟巨石项目的维护与开发都不太灵活。
以电商服务为例子来说,一个系统可以拆分成用户、交易、订单、商品、活动等多个功能模块,如果全部的功能都维护在一个项目里面,某些可以公用的模块(例如用户、权限等)就没办法共享给其他项目,项目的体积与代码复杂度也会逐步上升,导致后期维护与协同的成本会逐步增加。
但上述缺点都不是最主要的问题,最主要的问题是所有功能都放在一个系统里面开发部署,其中任意一个模块出现了问题都可能会导致整个系统雪崩。
对于一个应用的稳定性来说,如果没办法对单一的模块做熔断、升级、回滚等操作,线上不可控的概率极大,这也是目前主流采用微服务架构最大的原因之一。
但是,当一个系统的微服务模块数量非常多的情况下,也经常会出现以下问题:
- 通用性的认证、鉴权、限流等功能会导致每个微服务都存在造轮子的行为;
- 业务复杂度上升之后,存在域名分配的问题,没办法对每个服务都分配一个新的域名,同时每一个新的服务上线,运维重复配置的工作量多不少;
- 太多的域名服务对客户端并不友好,特别是请求层没有做 BFF 的话,每一次拆分新的微服务出来都可能会引起前端的改造;
- 并非每个服务都是同一种语言或者框架所开发,前面提到的公共的插件并不能满足所有的服务,这个情况可能在
DevOps
系统中比较常见。
为了解决上述的问题,网关系统随之诞生。我们可以通过网关的统一入口来调度各个微服务功能模块,使得每个微服务可以关注于自身的业务功能开发。
什么是网关系统(Gateway)
网关系统根据请求类型可以分为:
- 静态资源网关:处理前端资源数据包括 CSR、SSR 等;
- API 网关:随着微服务架构(MSA)的普及,通过统一的 API 网关可以聚合所有零散的微服务资源,保持统一的出入口,降低多项目的接入成本以及其他项目的使用成本。
从功能属性上可以分为:
- 流量网关:无关业务属性,单纯做安全(黑白名单)、分流(负载均衡)等;
- 业务网关:用户(认证、鉴权)、服务稳定性(降级、容灾)、业务属性灰度、代理(资源代理、缓存)、统一前置(日志、数据校验)等。
所以,市面上常见的网关系统除了提供请求聚合功能之外基本都包含所有通用功能:
- 认证(验证登录态,一般不做鉴权)
- 分流
- 代理(静态资源、API 等)
- AB test (流量灰度,一般根据 IP 或者用户信息灰度)
- 缓存(成本不低,看看就行)
- 等等
Gateway 功能拆解
通过上面对网关系统的简单了解和分析,我们能够知道,拥有网关系统对团队技术的价值贡献不小。那么如何实现一个网关系统呢?接下来,我们可以根据自己团队情况与需求,对将要实现的网关功能进行拆解,方便后期业务开发。
前文也提到了,业务网关最大的价值是与微服务架构的配合,如果后端服务没有使用微服务架构,网关的价值会打一定的折扣,所以具体是否需要网关服务还是需要结合团队的架构设计来考虑。同时在需求拆解的过程中要考虑侧重点,例如当前只需要完成前端静态资源转发就没必要去开发后端 API 转发的逻辑,可以把架构设计方案做大一点,后面有需求方便拓展,但没必要一次性全部做完,从团队的角度来考虑,寻求 ROI(投资回报率) 的最大化。
Nginx
Nginx
作为专业的 WEB
代理服务器,在代理方面能够提供负载均衡、流量切换等功能,脚本语言也有 lua
支持。
那么 Nginx
做不到什么呢?
Nginx
作为专业的转发服务器,对Session
以及Cookie
的处理比较弱。Nginx
仅仅支持HTTP
协议(Email
不算常用功能)。- 虽然可以通过
Lua
脚本来处理一些拓展的功能,但是Lua
脚本的变更以及修改Nginx
的配置都需要重新启动无法做到热更新,比较麻烦。 - 没有可视化管理界面也是一个比较大的硬伤(开源的有一些可视化配置项目,但跟可视化管理有一定的区别与差距)。
Gateway
业务性的 Gateway
需要做点啥:
- 统一鉴权收口,通过统一配置给接口资源添加权限;
- 支持
RPC
微服务调用,减少资源消耗; - 系统易于监控,同时可以采集收口进来的信息。
通过两者的对比可以看出,Nginx
更关注负载均衡以及反向代理,对业务部分的侵入很低,而 Gateway
作为后端应用,可以携带业务属性,两者可以很好的互补。
在系统架构设计上,我们可以使用 Nginx
作为上文所说的流量网关,由 Nginx
做一层流量代理,通过负载均衡到 Gateway
做业务层的转发处理,这样可以减少我们自建网关系统的工作量。
我们的网关系统设计
一个完整的网关系统是大而全的,接下来我们将挑选几个比较常见的模块来完成自研 Gateway
开发(如果目前团队欠缺或者自己有需求的话,可以接着使用 demo
项目继续优化,拓展需要的模块,达到理想可用的状态):
由上图可以看出,我们的网关系统架构可以分为两大模块,分别是代理转发的基础模块以及独立的用户模块。
- 网关基础服务
因为流量入口已经有 Nginx
作负载均衡,我们网关的基础服务就可以专注于代理模块的开发:
- 专注于前后端资源分发以及不同类型的项目 API 分发;
- 常用资源缓存模块;
- AB Test 模块;
- 通用日志模块。
- 统一用户中心系统
用户系统需要提供的功能有:
- 用户登录、认证等基础功能;
- 权限系统(基于 RBAC 包括角色、系统、资源等权限控制)。
如果当前团队中没有统一用户中心的话,建议将用户中心系统优先级提高,作为第一优先级的基建项目,完成之后可以赋能给予其他后端项目用户登录、鉴权的功能,可以减少其他后端基建的很多重复工作量。
- 物料系统
物料系统主要是针对于静态资源的管理,一般物料系统会跟 DevOps 体系关联比较大,毕竟物料会涉及构建部署的过程,但我们的主题并不是 DevOps,所以物料系统在小册的占比不会很高,只是作为一个辅助类型的项目为网关服务提供静态资源路由的配置、资源版本的管理等功能。
写在最后
本章主要针对网关系统的必要性做了简单分析,介绍了网关系统应用的场景以及网关的类型、作用等,最后针对我们要做的系统进行架构设计与功能拆解。
按照一个完整的项目迭代来说,在架构设计与需求模块都敲定之后,接下来就需要开发同学出技术方案进行项目开发,所以下一章我们将对技术方面的内容进行设计与规划。
如果你有什么疑问,欢迎在评论区提出或者加群沟通。 👏
NestJS 项目实战 - CookieBoty - 掘金小册从 0 搭建网关系统,玩转 NestJS 开发。「NestJS 项目实战」由CookieBoty撰写,2309人购买https://s.juejin.cn/ds/kb86fX9/