1.网关概述
采用分布式、微服务的架构模式开发系统时,API 网关是整个系统中必不可少的一环。
1.1 没有网关会有什么问题?
在微服务架构模式下,1个系统会被拆分成多个微服务,如果每个微服务都直接暴露给调用方,会有以下问题:
-
调用方直接调用不同的微服务,增加调用方的代码复杂性,维护起来非常复杂
-
调用方记录和管理每个微服务的接口,缺乏安全性
-
需要在每个微服务中增加对用户的认证和鉴权逻辑或者限流的逻辑,代码冗余
-
由于每个微服务部署的服务器不同,存在跨域的请求
1.2 增加API网关服务
上面的问题都可以借助 API 网关来解决。所谓的API网关,就是指系统的统一入口**,所有的外部请求率先经过网关,调用方只需要知道网关的地址,与网关交互即可。**
它屏蔽了系统的内部复杂结构,为调用方提供统一服务。
一些与业务功能无关的公共逻辑可以在这里实现,例如认证、授权、限流、监控、路由转发等等。
2.主流的网关解决方案
业界通过不断的探索与创新,出现了多种API网关的解决方案。
现在比较主流的API网关有以下几种:
1. Nginx + Lua
Nginx 是一个高性能的HTTP和反向代理服务器,Nginx 一方面可以做反向代理,另一方面可以做静态资源服务器。
Nginx 的一些常用插件本身就实现了限流、缓存、黑白名单和灰度发布的功能,再加上 Nginx 的反向代理和负载均衡,便能够实现对服务接口的负载均衡和高可用。
而 Nginx 支持 Lua 语言,通过 Lua 语言可以完成简单的业务逻辑实现。所以可以基于 Nginx+Lua 脚本实现 API 网关,较麻烦。
2. Kong
Kong 网关本身是基于 Nginx + Lua 实现的,但比 Nginx 提供了更简单的配置方式,数据采用了ApacheCassandra/PostgreSQL储存,性能高并且比较稳定,并且提供了一些优秀的插件,例如验证、日志、调用频次限制等。Kong 网关提供了大量的插件来扩展应用,通过设置不同的插件可以为服务提供各种增强的功能,并且提供了管理页面。
但是和 SpringCloud 整合比较难,并且只支持 http 协议;进行二次开发和自由扩展困难。
3.Zuul
Zuul 是 NetFlix 公司开源的一个 API网关组件,SpringCloud 对其进行二次开发基于 SpringBoot 注解式封装做到开箱即用。目前来说结合 SpringCloud 提供的服务治理体系,可以做到请求转发,根据配置或者默认的路由规则进行路由和负载均衡,无缝继承 Hystrix。
Zuul 本身是的设计是基于单线程的接收请求和转发处理,是阻塞 IO,不支持长连接,2.0开始支持异步调用模式。
但是 Zuul 网关无法实现动态配置规则,依赖的组件相对来说也比较多,处理 http 请求依赖的是 web容器,在性能上不如 Nginx。
4.SpringCloud Gateway
SpringCloud Gateway 作为 SpringCloud 生态系统中的网关,目标是替代 Zuul,其不仅提供了统一的 API 路由管理方式,并且还基于 Filter 链的方式提供了网关的基本功能,例如:安全、监控、重试、限流等。
优点:
-
性能是第一代网关 Zuul 的 1.6 倍
-
功能强大:内置了很多实用的功能,例如:路由转发、监控、限流等
-
简单易用、设计优雅、容易扩展
缺点:
-
其实现依赖于 Netty 和 WebFlux,不是传统的 Servlet 编程模型,基于响应式编程,源码学习成本高
-
需要 Spring Boot 2.0 以上才能支持
-
性能相对 zuul2、openrestry、nginx、kong来说是最差的,但是轻量级的网关系统还是首选gateway,出现性能瓶颈可以通过多加几台服务器的方式解决
SpringCloud Alibaba 技术栈中,并没有单独实现网关的组件。所以在我们的系统实现中,会使用SpringCloud Gateway 实现 API 网关功能。