API网关是一个服务器,系统的唯一入口。从面向对象设计的角度看,它与外观模式类似。核心要点是,所有的客户端和消费端都通过统一的网关接入微服务,在网关层处理所有的非业务功能,API网关封装了系统内部架构,为每个客户端提供一个定制的API。
路由是微服务网关的核心能力。通过路由功能微服务网关可以将请求转发到目标服务。在微服务架构中,网关可以结合注册中心的动态服务发现,实现对后端服务的发现,调用方只需要知道网关对外暴露的服务API就可以透明地访问后端微服务。
API网关结合负载均衡技术,利用Eureka或者Consul等服务发现工具,通过轮询、指定权重、IP地址哈希等机制实现下游服务的负载均衡。
一般而言,无论对内网还是外网的接口都需要做用户身份认证,而用户认证在一些规模较大的系统中都会采用统一的单点登录(Single Sign On)系统,如果每个微服务都要对接单点登录系统,那么显然比较浪费资源且开发效率低。API网关是统一管理安全性的绝佳场所,可以将认证的部分抽取到网关层,微服务系统无须关注认证的逻辑,只关注自身业务即可。
API网关可以为外部客户端提供RESTful API,即使内部的服务使用混合的通信协议,例如REST、gRPC等。这样做的好处是,对于外部客户端而言,服务端更像是一个不可见的黑盒。
对于一些幂等的get请求,可以在网关层面根据业务方指定的缓存头做一层缓存,存储到Redis等二级缓存中,这样一些重复的请求,可以在网关层直接处理,而不用打到业务线,降低业务方的压力,另外如果业务方节点挂掉,网关也能够返回自身的缓存。也可以一些修改频率不高的数据。例如:用户信息,配置信息,通过服务定期刷新这个缓存就行了。
API网关还提供了API聚合的操作。以淘宝详情页为例,如果单独获取视频、商品价格、商品评论等信息,需要发多个请求(getVideo,getPrice,getComments)。有了API网关后,可以将API接口组合起来,通过一次请求(getItemDetail)来获取需要的信息,这样可以极大的改善由于网络延时导致的差用户体验。
网关可以统计后端服务的请求次数,并且可以实时地更新当前的流量健康状态,可以对URL粒度的服务进行延迟统计,也可以使用Hystrix Dashboard查看后端服务的流量状态及是否有熔断发生。
在某些场景下需要控制客户端的访问次数和访问频率,一些高并发系统有时还会有限流的需求。在网关上可以配置一个阈值,当请求数超过阈值时就直接返回错误而不继续访问后台服务。当出现流量洪峰或者后端服务出现延迟或故障时,网关能够主动进行熔断,保护后端服务,并保持前端用户体验良好。
API网关可以使用系统黑名单,过滤HTTP请求特征,拦截异常客户端的请求,例如DDoS攻击等侵蚀带宽或资源迫使服务中断等行为,可以在网关层面进行拦截过滤。比较常见的拦截策略是根据IP地址增加黑名单。在存在鉴权管理的路由服务中可以通过设置白名单跳过鉴权管理而直接访问后端服务资源。
和灰度发布的原理相似,网关可以根据HTTP请求的Host、Head、Agent等标识对请求进行染色,有了网关的流量染色功能,我们可以对服务后续的调用链路进行跟踪,对服务延迟及服务运行状况进行进一步的链路分析。
网关结合Swagger,可以将后端的微服务暴露给网关,网关作为统一的入口给接口的使用方提供查看后端服务的API规范,不需要知道每一个后端微服务的Swagger地址,这样网关起到了对后端API聚合的效果。
微服务网关可以作为统一的日志记录和收集器,对服务URL粒度的日志请求信息和响应信息进行拦截。
本质上看API网关也是做了请求的转发,Nginx做负载均衡时,考虑到API网关在系统中不止一个(以集群的方式做高可用),可以将Nginx至于API网关前,负责对API网关的负载均衡,然后再由网关决定进入到哪个真实的web 服务器。 这样就可以让两者的分工更加明确:API网关聚合服务,Nginx请求转发。
Nginx是一个高性能的HTTP和反向代理服务器。Nginx一方面可以做反向代理,另外一方面可以做静态资源服务器,接口使用Lua动态语言可以完成灵活的定制功能。
Kong是一款基于OpenResty(Nginx + Lua模块)编写的高可用、易扩展的,由Mashape公司开源的API Gateway项目。Kong是基于NGINX和Apache Cassandra或PostgreSQL构建的,能提供易于使用的RESTful API来操作和配置API管理系统,所以它可以水平扩展多个Kong服务器,通过前置的负载均衡配置把请求均匀地分发到各个Server,来应对大批量的网络请求。
Kong主要有三个组件:
Kong Server :基于Nginx的服务器,用来接收API请求。
Apache Cassandra/PostgreSQL:用来存储操作数据。
Kong dashboard:官方推荐UI管理工具,也可以使用 restful 方式管理。
Kong采用插件机制进行功能定制,插件集(可以是0或N个)在API请求响应循环的生命周期中被执行。插件使用Lua编写,目前已有几个基础功能:HTTP基本认证、密钥认证、CORS(Cross-Origin Resource Sharing,跨域资源共享)、TCP、UDP、文件日志、API请求限流、请求转发以及Nginx监控。
Zuul 是 Netflix 开源的一个API网关组件,它可以和 Eureka、Ribbon、Hystrix 等组件配合使用。社区活跃,融合于 SpringCloud 完整生态。Zuul 的核心是一系列的过滤器,借助过滤器实现以下功能:
统一鉴权 + 动态路由 + 负载均衡 + 压力测试
审查与监控:与边缘位置追踪有意义的数据和统计结果,从而带来精确的生产视图。
弹性负载均衡
2.3.1 Zuul1
Zuul目前有Zuul1 和 Zuul2两大版本。其中,Zuul1 是zuul基于Servlet实现。当一个请求进来时,会先进入 pre 过滤器,在 pre 过滤器执行完后,接着就到了 routing 过滤器中,开始路由到具体的服务中,错误的情况会被错误过滤器拦截。处理方式采用的是阻塞和多线程方式,即一个线程处理一次连接请求,这种方式在内部延迟严重、设备故障较多情况下会引起存活的连接增多和线程增加的情况发生。侧重计算密集型(CPU bound 场景),轻I/O的场景,不支持长连接.
优势 |
劣势 |
编程模型简单 |
线程上下文切换会消耗CPU内存资源 |
开发调试运维简单 |
连接数有限制 |
Debug调试好跟踪 |
阻塞会耗尽链接资源,抖动甚至崩溃 |
2.3.2 Zuul2
Zuul 2 和 Zuul 1 在架构方面的主要区别在于,Zuul 2 运行在异步非阻塞的框架上,比如 Netty,引入事件、总线、队列机制、事件环处理,每个 CPU 核上一个线程,处理所有的请求和响应,请求和响应的生命周期是通过事件和回调来处理的,这种方式减少了线程数量,因此开销较小。适用于I/O密集型场景。
优势 |
劣势 |
线程开销少 |
编程模型复制,没有清晰的线程执行流 |
连接数量大,易扩展 |
开发调试运维复杂 |
cat等全链路监控依ThreadLocal不容易集成 |
Spring Cloud Gateway(SCG)是Spring Cloud的一个全新的API网关项目,目的是为了替换掉Zuul1,它基于Spring5.0 + SpringBoot2.0 + WebFlux(基于⾼性能的Reactor模式响应式通信框架Netty,异步⾮阻塞模型)等技术开发,性能⾼于Zuul,官⽅测试,Spring Cloud GateWay是Zuul的1.6倍,旨在为微服务架构提供⼀种简单有效的统⼀的API路由管理⽅式。
SCG 可以与Spring Cloud Discovery Client(如Eureka)、Ribbon、Hystrix等组件配合使用,实现路由转发、负载均衡、熔断、鉴权、路径重写、⽇志监控等,并且Gateway还内置了限流过滤器,实现了限流的功能。
SCG主要围绕Route、Predicate、Filter进行展开。路由Route,handler为Predicate断言路由的匹配条件,如果配置多个需要同时满足才可匹配,Gateway已经内置了多种实现,如:Path、Method、Host等;Filter:过滤器,对请求进行拦截,可实现自定义的功能。按照作用范围分为:GatewayFilter(应用到单个路由或者一个分组的路由上)和GlobalFilter(应用到所有的路由上)。
执行步骤如下:
Traefic是一个为了让部署微服务更加便捷而诞生的现代HTTP反向代理、负载均衡工具。 它支持多种后台 (Docker, Swarm, Kubernetes, Marathon, Mesos, Consul, Etcd, Zookeeper, BoltDB, Rest API, file…) 来自动化、动态的应用它的配置文件设置。
Traefik较为轻量,非常易于使用和设置。通过Kubernetes存储状态(Kong要使用Postgres或者Cassandra来存储状态),并利用Ingress通过https将所有流量路由到对应的服务。Traefik带有自己的仪表板,它始终与最新的Traefik版本兼容。
Kong |
Zuul |
gateWay |
Traefic |
|
实现语言 |
C/Lua |
Java |
Java |
Golang |
基于 |
Kong+Nginx |
Zuul |
Gateway |
traefik |
是否开源 |
Y |
Y |
Y |
Y |
社区star |
20000+ |
2000+ |
依靠Spring社区 |
20000+ |
K8s部署 |
适中(k8S yaml/helm chart) |
适中(k8S yaml/helm chart) |
适中(k8S yaml/helm chart) |
easy |
服务发现 |
动态 |
动态 |
动态 |
动态 |
支持协议 |
http/https/websocket |
http/https |
http/https/websocket/grpc |
http/https/websocket/grpc |
SSL终止 |
Y |
N |
N |
Y |
路由 |
Host,path,method |
能够匹配任何请求属性 |
能够匹配任何请求属性 |
Host,path |
限流 |
Y |
过滤器自研 |
过滤器自研 |
N |
熔断 |
Y |
需要其他组件 |
需要其他组件 |
Y |
重试 |
Y |
Y |
Y |
Y |
健康检查 |
Y |
Y |
Y |
N |
负载均衡 |
轮询,哈希 |
轮询、随机加权轮询、自实现 |
轮询、随机加权轮询、自实现 |
轮询、加权轮询 |
权限 |
Basic Auth, HMAC, JWT, Key, LDAP, OAuth 2.0, PASETO, plus paid Kong Enterprise options like OpenID Connect |
开发实现 |
开发实现 |
basic |
链路跟踪 |
Y |
需要其他组件 |
需要其他组件 |
Y |
dashboard |
Y |
N |
N |
Y |
扩展功能 |
Lua编辑插件 |
自实现 |
自实现 |
自实现 |
扩展方法 |
水平 |
水平 |
水平 |
水平 |
亮点 |
高性能,可编程API |
成熟,简单门槛低 |
异步,配置灵活 |
云原生,可编程API/对接各种服务发现 |
注:
SSL卸载:为了帮助缓解SSL/TLS增加的额外负担,可以启动单独的、特定于应用程序的集成电路(ASIC)处理器,这些处理器仅限于执行SSL/TLS所需的功能,即握手和加密/解密。这将可以为目的应用程序或网站释放出处理能力。
SSL实现方式:SSL终止和SSL桥接
SSL终止:用于SSL卸载的代理服务器或负载均衡器充当着SSL终结器的角色,它也充当边缘设备的角色。当客户端尝试连接到网站时,客户端就会连接到SSL终结器——该连接是HTTPS。但是SSL终结器和应用服务器之间的连接是通过HTTP连接的。
SSL桥接:SL桥接在概念上与SSL终结非常相似,它会在将所有内容发送到应用程序服务器之前,重新加密它们。
Fizz Gateway 是一个基于 Java开发的微服务聚合网关,能够实现热服务编排聚合、自动授权选择、线上服务脚本编码、在线测试、高性能路由、API审核管理、回调管理等目的,拥有强大的自定义插件系统可以自行扩展,并且提供友好的图形化配置界面,能够快速帮助企业进行API服务治理、减少中间层代码以及降低编码投入、提高 API 服务的稳定性和安全性。
访问地址:http://demo.fizzgate.com/
账户密码:admin/Aa123!
Gitlab地址:fizz-gateway: 微服务API聚合网关 An Aggregation API Gateway
开发文档:路由管理 | Fizz Gateway
Apache ShenYu是使用Java reactor编程方式开发的,具有异步,高性能,跨语言等特性的 API 网关。 在流量控制方面,有精美的Admin控制台,能够精准,动态控制流量,满足复杂的业务场景。 在功能方面,它使用插件化的设计思想,支持许多常见的协议:如 http/https, Dubbo、 Spring Cloud、 GRPC、 Motan、 Sofa、 Tars 等。 同时内置十分丰富的功能插件,如 熔断,限流,鉴权,黑白名单,防火墙,监控,参数更改等等插件.
对流量的控制是网关的灵魂,针对流量控制,Apache ShenYu 设计了选择器,规则 2个概念,来控制流量。
选择器和规则是 Apache ShenYu 网关中最灵魂的东西。一个插件有多个选择器,一个选择器对应多种规则。选择器相当于是对流量的一级筛选,规则就是最终的筛选。对于插件,希望根据配置达到满足条件的流量,插件才会被执行。
选择器和规则就是为了让流量在满足特定的条件下,才去执行。
插件、选择器和规则执行逻辑如下,当流量进入到Apache ShenYu网关之后,会先判断是否有对应的插件,该插件是否开启;然后判断流量是否匹配该插件的选择器。然后再判断流量是否匹配该选择器的规则。如果请求流量能满足匹配条件才会执行该插件,否则插件不会被执行,处理下一个。
为了提升网关的性能,Apache ShenYu 网关会将所有的流量控制规则缓存在JVM 内存里面。在集群部署/分布式场景中,Apache ShenYu 自主研发了一套将 Admin 控制台的数据,远程同步到每一个 Apache ShenYu 网关节点 JVM内存的方案。每一种方案,采用 SPI 设计思想,以供用户灵活的选择。目前支持的方案有 HttpLongPull, Websocket, Zookeeper, Nacos, Consul, ETCD。
目前Apache ShenYu支持http、Websocket、Dubbo、Spring Cloud、GRPC、Motan、Sofa、Tars等协议的转换。
参考链接:Apache ShenYu 介绍 | Apache ShenYu
特性支持 |
ShenYu |
Fizz |
可视化管理平台 |
Y |
Y |
路由规则 |
调用方根据请求url(原始url)路由,支持模糊匹配、正则等。自身提供了相关插件,可以对url的映射作简单调整 |
支持网关节点进行分组,不同的网关节点支持不同的路由规则。根据url路由,支持url别名映射路由。路由类型支持:服务编排、服务发现、反向代理 |
插件作用域 |
应用级别、接口级别 |
服务(接口)级别 |
服务信息暴露 |
自动注册(代码浸入)、手工相对烦琐 |
手工维护,服务提供方层面代码无侵入 |
多语言支持 |
java 支持自动注册,其它语言手工配置 |
无代码浸入,手工注册http接口,语言无关性 |
支持的协议 |
http\springcloud\websocket \dubbo\tars\soaf\grpc\motan |
http\https\springcloud\dubbo\grpc |
定义插件配置 |
支持,并且相当灵活,自定义插件采用maven依赖方式,代码无耦合 |
支持,但是需要在fizz上开发,代码耦合 |
服务编排 |
N |
Y |
默认插件 |
支持多种:鉴权、熔断、限流、流量白名单 |
仅支持鉴权、流控 |
用户权限配置 |
支持 |
支持 |
是否开源 |
完全开源 |
控制台需要商业授权 |
监控 |
支持prometheus |
自带监控面板 |
插件作用域 |
针对具体请求 |
全局 |