笔者最近在学习网关方面的知识,网关也是系统架构的主要核心,本文也是对理论知识与技术选择 的总结
在架构思考的时候我们都知道,通常我们由一个域名绑定一个或多个ip,服务到我们系统部署的门户网关,这类型的网关负责对整个服务集群的负载均衡功能和统一入口,毕竟再复杂的系统对用户来说应该都只有一个统一访问路径,这样子的统一访问路径通常对用户来说是一个域名。对于一个域名而言它的功能就是映射到某个ip,而这个ip再转发给我们的内部服务。
从上图可以看出对于这样子的网关,是一个系统的流量统一入口(先不考虑门户网关的集群部署),毋庸置疑的是所有请求流量都会经过这里,对于性能的考验是很大的。
通常我们的业务服务(如图所示)是不对外暴露的,而门户网关也有个核心定位是,将外部请求转发到内部服务中,避免服务直接在公网暴露。
这样的网关通常我们不做过多的业务操作
为何不做过多的业务操作
- 统一入口性能要求高
- 主流高性能门户网关脚本编码麻烦
- 业务需求应该在业务服务里做
将一些服务共有的功能整合在一起,独立部署为单独的一层,用来解决一些服务治理的问题。你可以把它看作
系统的边界,它可以对出入系统的流量做统一的管控。
是对业务网关的定义
成熟的系统需要做些功能限流、拦截、鉴权等等这些功能如果在每个业务服务中集成(每个jar包中带有),可想而知的不好维护、业务服务关心的层面变多,统一的抽取出并作为业务处理的上层,这种设计是更加优秀的。
那为为何这些不放在门户网关呢:
- 门户网关本来只要做转发,添加业务需求后将会变的复杂,且性能下降
- 通常业务主语言的java、go、python等此类语言与门户网关的编码语言不符
门户网关: 门户网关的特性主要作为系统的统一入口,并不再网关上做过多的业务所以也没有大量的编码工程,而主考虑的是性能是否满足与自带功能是否丰富
业务网关:此类网关如上文所说承担着限流、拦截、鉴权等等功能,会持续的更新、新增业务需求,那对于这样子的特殊服务,应该符合公司的主流语言、架构团队熟悉的,能够快速高质量的写出业务代码,而非只为了性能选择架构,当然性能也是极其重要的,在主语言选择后就是考虑性能。
在实现一个 API 网关时,要考虑的是它的性能。这很好理解,API 入口网关承担从客户端的所有流量。假如业务服务处理时间是 10ms,而 API 网关的耗时在 1ms,那么相当于每个接口的响应时间都要增加 10%,这对于性能的影响无疑是巨大的。而提升 API 网关性能的关键还是在 I/O 模型上,这里只是举一个例子来说明 I/O 模型对于性能的影响。
Netfix 开源的 API 网关 Zuul 2.0的I/O 多路复用就比Zuul 1.0同步阻塞 I/O 模型性能提升了 20%
此外还有许多关键词:
- IO 多路复用 VS 多线程
- IO模型 select/poll 和 epoll
- 线程模型
- 线程隔离
网关中执行的动作有些是可以预先定义好的,比如黑白名单的设置、接口动态路由;有些则是需要业务方依据自身业务来定义。所以,API 网关的设计要注意扩展性,也就是你可以随时在网关的执行链路上,增加一些逻辑,也可以随时下掉一些逻辑(也就是所谓的热插拔)。
引用Zuul设计:把每一个操作定义为一个 filter(过滤器),然后使用“责任链模式”将这些 filter 串起来。责任链可以动态地组织这些 filter,解耦 filter 之间的关系,无论是增加还是减少 filter,都不会对其他的 filter 有任何的影响。
排自研以外,社区活跃度是非常重要的考虑方面,对一个中小型公司,没有强大的自研能力,社区的是否活跃是非常关键的。选择社区活跃的项目能在使用和二次开发上有极大的帮助,同时社区活跃也代表了一定的稳定性。
毋庸置疑,Nginx是目前最流行的门户网关没有之一,可选很多第三方扩展模块,原生支持js/perl脚本,非官方支持lua,模块化,按需编译。
Nginx的定位是一个server,Haproxy的定位是一个load balancer。 Nginx通过各种plugin module可以支持Load balance的功能,而且性能不弱于haproxy太多
项目名 | 二次开发语言 | 性能 | 扩展性 | 社区活跃度 | 描述 |
---|---|---|---|---|---|
Nginx | Lua | 好 | 极高 | 极其活跃 | 主流选择 |
LVS | 最好 | 不易 | 活跃 | 不能动静分离,功能比较简单,维护复杂 | |
HAProxy | Lua | 极好 | 不易 | 活跃 | 性能比Nginx更佳,免费开源,稳定性 |
相比门户网关业务网关基本上都是主流高级语言,扩展都相对容易,主语言是Java在选择上更推荐Shenyu,拥有优秀的界面。而Kong这类基于Nginx的性能毋庸置疑的最优,最求极致性能可以选择。
项目名 | 二次开发语言 | 性能 | 扩展性 | 社区活跃度 | 描述 |
---|---|---|---|---|---|
Gateway | Java | 够好 | 容易 | 活跃 | 无界面,Spring公司推出 |
Kong | Lua | 最好 | 一般 | 活跃 | 基于Nginx性能最优,有界面 |
ShenYu | Java | 够好 | 容易 | 活跃 | Apache顶级项目,界面优秀 |
Tyk | GO | 够好 | 容易 | 较少 | Go编写,有界面 |
对于笔者而言这两种网关是笔者的必修课,会单独开一篇文章来聊聊
—EOF—