1. 应用网关的介绍
在互联网早期的时候,其实单web应用也能支撑用户的请求,因为请求量并不大。 但是随着需求的增多,单应用已无法承受更多的请求, 人们就把应用部署在多个服务器上,以支撑更多的用户请求,那这里就会产生一个问题,后端有多少服务器支撑用户并不需要,用户只会请求某个地址来获得服务,那么这个地址如何将请求转发到服务上以实现均衡的负载呢? 这就是网关需要做的事情。
为了解决这个问题,人们提出了网关(gateway)的概念,网关能够做为某种翻译器使用,它抽象出了一种可以到达资源的方法。网关是资源和应用程序之间的粘合剂。应用程序能够(经过HTTP或其余已定义的接口)请求网关来处理某条请求,网关能够提供一条响应。网关能够向数据库发送查询语句,或者生成动态的内容,网关就像一个门一样:进去一条请求,出来一个响应。
大家都知道,从一个房间走到另一个房间,必然要经过一扇门。同样,从一个网络向另一个网络发送信息,也必须经过一道“关口”,这道关口就是网关。顾名思义,网关(Gateway) [1] 就是一个网络连接到另一个网络的“关口”。也就是网络关卡。
随着网络应用的复杂化,人们提出了微服务的解决方案,在微服务架构中,一个系统会被拆分为很多个微服务。那么作为客户端要如何去调用这么多的微服务呢?如果没有网关的存在,我们只能在客户端记录每个微服务的地址,然后分别去调用。这样的话会产生很多问题。 例如:
-
客户端多次请求不同的微服务,增加客户端代码或配置编写的复杂性
-
认证复杂,每个微服务都有独立认证
-
存在跨域请求,在一定场景下处理相对复杂
为解决上面的问题,所以我们引入了网关,也就是系统的统一入口,对外暴露给用户,对内提供路由转发,负载均衡等,同时一些与业务本身功能无关的公共逻辑可以在网关中实现,诸如认证、鉴权、监控、日志几率等。
从上两张图可以看出网关作用在哪个环节,网关也是可以集群提供高可用的,不然一个网关挂了,应用整体就无法提供服务了。
2. 微服务中网关的对比
名称 | 公司 | 性能 | 易用性 |
---|---|---|---|
Zuul 1.x | Netflix | 低 | 较好 |
Zuul 2.x | Netflix | 高 | 较好 |
Spring Cloud Gateway | Apache官方 | 较高 | 比较好 |
Nginx+lua | - | 很高 | 低 |
Kong | Mashape | 很高 | 低 |
-
Zuul 1.x Netflix开源的网关,基于Servlet框架构建,功能丰富,使用JAVA开发,易于二次开发 问题:即一个线程处理一次连接请求,这种方式在内部延迟严重、设备故障较多情况下会引起存活的连接增多和线程增加的情况发生。
-
Zuul 2.x Zuul2 采用了Netty实现异步非阻塞编程模型,每个 CPU 核一个线程,处理所有的请求和响应,请求和响应的生命周期是通过事件和回调来处理的,这种方式减少了线程数量,因此开销较小。
-
GateWay Spring公司为了替换Zuul而开发的网关服务,底层为Netty,将在下面具体介绍。
-
Nginx+lua 使用nginx的反向代理和负载均衡可实现对api服务器的负载均衡及高可用,lua是一种脚本语言,可以来编写一些简单的逻辑, nginx支持lua脚本,问题在于:无法融入到微服务架构中
-
Kong 基于Nginx+Lua开发,性能高,稳定,有多个可用的插件(限流、鉴权等等)可以开箱即用。 问题:只支持Http协议;二次开发,自由扩展困难;提供管理API,缺乏更易用的管控、配置方式。
3. Spring Cloud Gateway
网关的搭建
基于微服务架构,一般我们都会推荐使用官方的Spring Cloud Gateway作为网关,但就算有了这个业务网关,我们也一般会在业务网关之前再搭建一层高性能的流量网关Nginx来应对更高的并发请求,如果有更大更高的并发请求,我们还会在流量网关之前再建一层LVS+keepalived来这样可以实现进来的流量和出去的流量在服务器级别进行分流处理。 如果还有更大的流量,可以做地域动态域名解析来应对。
刚开始的时候,我们有Spring Cloud Gateway足以。
介绍
Spring Cloud Gateway 基于Spring Boot 2.x、Spring WebFlux和Project Reactor,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。它的目标是替代Netflix Zuul,其不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控和限流。
Spring Cloud Gateway可以与Spring Cloud Discovery Client(如Eureka)、Ribbon、Hystrix,Alibaba Nacos/Sentinel等组件配合使用,实现路由转发、负载均衡、熔断、鉴权、路径重写、⽇志监控等,并且Gateway还内置了限流过滤器,实现了限流的功能。
特点:
-
性能强劲:是Zuul的1.6倍
-
功能强大:内置了很多实用的功能,例如转发、监控、限流等
-
设计优雅,容易扩展
基本概念
路由(Route) 是 gateway 中最基本的组件之一,表示一个具体的路由信息载体。主要定义了下面的几个信息:
-
id:路由标识、区别于其他route
-
uri:路由指向的目的地uri,即客户端请求最终被转发到的微服务
-
order:用于多个route之间的排序,数值越小排序越靠前,匹配优先级越高
-
predicate:断言的作用是进行条件判断,只有断言都返回真,才会真正的执行路由
-
filter:过滤器用于修改请求和响应信息
执行流程
-
Gateway Client向Gateway Server发送请求
-
请求首先会被HttpWebHandlerAdapter进行提取组装成网关上下文
-
然后网关的上下文会传递到DispatcherHandler,它负责将请求分发给RoutePredicateHandlerMapping
-
RoutePredicateHandlerMapping负责路由查找,并根据路由断言判断路由是否可用
-
如果过断言成功,由FilteringWebHandler创建过滤器链并调用
-
请求会一次经过PreFilter--微服务--PostFilter的方法,最终返回响应
总结
SpringCloud GateWay使用的是Webflux中的reactor-netty响应式编程组件,底层使用了Netty通讯框架。