微服务网关介绍
认识微服务网关
随着微服务架构中的服务不断增加,一定会出现多个服务地址(IP
地址+端口号),每个服务中也有多个接口地址,进而会出现多个服务接口地址。客户端想要调用项目中的接口就需要使用多个地址,而维护多个地址是很不方便的,这时就需要一个组件对这些接口地址进行管理。
图9-1 是每个微服务实例中的地址直接暴露给调用端。
这种处理方式主要有如下几个问题。
-
客户端调用服务的问题。在微服务架构内除使用
HTTP
通信外,还有RPC
通信和其他通信方式。不论使用哪种通信方式,都是微服务间的信息传递,属于架构内服务与服务的通信方式。如果某些服务使用了不同的通信方式,这种直接暴露接口的方式让客户端不得不处理不同的通信方式,无法做到统一。Figure 1. 图9-1 每个微服务实例中的地址直接暴露给调用端 -
暴露给用户的接口地址太多,并且地址的写法不固定,难以管理。
-
不安全与不可控的问题。比如,微服务 2 中有 20 个接口,其中 19 个接口是供其他微服务调用的底层接口,向用户层开放的只有 1 个接口。全部开放就会出现不安全和不可控的情况,用户会访问不属于自身权限的功能。
-
无法做到统一的前置处理。在请求到达各服务实例前,如果需要对用户进行权限认证或定制化的拦截,就需要在每个服务实例中进行编码,在真实的项目开发中需要避免出现这个问题。
在 Spring Cloud
一站式解决方案中,早早地给出了服务网关这个组件来解决上述问题。
在微服务架构中整合网关组件后,就打通了客户端到微服务架构内部的通道,也算架起了一座桥梁。通过服务网关为请求提供了统一的访问入口,同时也能够对请求做一些定制化的前置处理,如图 9-2 所示。

微服务网关的作用如下。
-
统一通信方式,减少客户端的接入难度。可以使用服务网关对外提供
RESTful
风格的接口,请求到达网关后,由网关组件将请求转发到对应的微服务中。 -
服务网关作为客户端到微服务架构的唯一入口,管理所有的接入请求,可以统一接口的
URL
写法。同时,也能够作为一道屏障,屏蔽一些后端服务的处理细节。 -
服务网关可以对后端各个服务做统一的管控和配置管理,用于保护、增强和控制对后端服务的访问。
-
服务网关可以做一些定制化编码,对请求进行统一的处理和拦截,从而完成一些前置处理,隐藏在微服务网关后面的业务系统就可以更加专注于业务本身。
微服务网关是微服务架构中一个非常关键的角色,作为后端服务的统一入口,负责统筹和管理后端服务。服务网关提供的功能有路由、负载均衡、安全认证、流量染色、灰度发布、限流熔断、协议转换、接口文档中心、日志收集等。
网关层的主流技术选型
其实,一提到 “网关” 这个词,大部分读者的脑海中会立刻想到 Nginx
、Apache
、Kong
这些产品。尤其是后端开发人员,对 Nginx
、OpenResty
这两个产品应该更熟悉。图 9-3 是 2021 年 11 月 23 日 Netcraft
发布的全球 Web
服务器调查报告。

该报告中显示,前文中提到的 Apache
、Nginx
、OpenResty
这三个产品的总市场占有率达到了 66.03%,数据见表 9-1。

通过数据可以很直观地看出这些产品在全球各个企业里的应用非常广泛。既然这些产品已经这么 “能打” 了,为什么还要引入一个新的网关组件呢?难道是 Spring Cloud
提供的网关组件性能太强了?还是说 Spring Cloud
官方 “护犊子”,不允许使用其他网关组件呢?其实都不是,微服务网关组件与 Nginx
这类网关产品的定位是不同的,微服务网关是微服务架构内部的网关组件,算底层的组件,而 Nginx
是更上层的网关。如图 9-4 所示,从客户端发送的请求真正到达微服务层,是需要经过两层甚至多层网关的。

这里以平时回家刷门禁卡的流程做一个简单的类比。到达小区大门时,一般无法立刻进入小区,可能需要刷门禁卡或刷脸识别,成功后小区大门才会打开,到家门口时也无法立刻进入家门,需要用钥匙开门或刷门禁卡后才能进门。在此场景中,“小区大门” 相当于上层的网关,面向需要进入整个小区的人员,而 “家门” 相当于下层的网关,只负责一个家庭的人员。与小区大门前的门禁设备相比,家里的门锁只负责自己家庭成员的身份信息验证。类比到网关产品中,与 Nginx
、OpenResty
这类上层网关相比,微服务网关的功能和应用更加聚焦一些,只负责微服务架构中的网关工作,如图 9-5 所示。

常见的网关技术选型整理如下。
-
Nginx+Lua
Nginx
是一个高性能的HTTP
和反向代理服务器,使用Lua
动态脚本语言可以完成灵活的定制功能。Nginx
一方面可以做反向代理,另一方面可以做静态资源服务器。Nginx+Lua
脚本的组合是网关层技术选型中比较常见的,如OpenResty
网关就是以此为底层基础的。开发人员可以使用Lua
脚本语言调用Nginx
支持的模块完成网关层的功能开发和配置。笔者在刚开始接触微服务架构时,微服务网关的选型就是
OpenResty
,Lua
脚本也比较简单。不过,Spring Cloud
比较推荐自家的网关产品,后期笔者就选择了Netflix Zuul
和Spring CloudGateway
。这并不意味着OpenResty
就没人用了,它依然是一个非常优秀的产品,在其他领域发挥着它的作用。 -
Kong
Kong
是一个轻量级、快速、灵活的云原生API
网关,可以让开发人员很方便地管理、配置项目中的各个接口。它本身是基于Nginx+Lua
的,但提供了比Nginx
更简单的配置方式,可以用与之配套的开源软件Kong
实现在Web
页面上配置和管理接口。 -
Netflix Zuul
Zuul
是Netflix
公司开源的一个API
网关组件,结合Spring Cloud
提供的服务治理体系,可以完成请求转发、路由规则配置、负载均衡和集成Hystrix
实现熔断功能。在早期Spring Cloud
与Netfilx
合作时,Zuul
是Spring Cloud
微服务架构解决方案中的首选网关产品。 -
Spring Cloud Gateway
Netflix
套件不更新了。Netflix Zuul 1
版本进入维护期,Netflix Zuul 2
版本宣布闭源,于是Spring
官方推出了一款微服务网关组件,就是本章的主角——Spring Cloud Gateway
。虽然后来Netflix Zuul 2
版本又宣布开源了,但是覆水难收,Spring Cloud
微服务架构解决方案中的首选网关产品已经易主了。Spring Cloud Gateway
官方介绍如下:This project provides a library for building an API Gateway on top of SpringWebFlux.Spring Cloud Gateway aims to provide a simple,yet effective way to route to APIsand provide cross cutting concerns to them such as:security,monitoring/metrics,andresiliency.
Spring Cloud Gateway
是基于Spring WebFlux
的高性能网关产品,它旨在为微服务架构提供一种简单、高效的API
路由管理方式,并为它们提供跨领域的关注点,如安全、监控指标、熔断等。为了提升网关的性能,Spring Cloud Gateway
是基于WebFlux
框架实现的,而WebFlux
框架底层则使用了高性能的Reactor
模式通信框架Netty
。以下是
Spring Cloud Gateway
的关键特征。-
基于
Spring Framework 5+Project Reactor+Spring Boot 2.0
构建。 -
能够匹配任何请求属性上的路由。
-
集成了熔断器。
-
集成了
Spring Cloud DiscoveryClient
。 -
断言和过滤器的编码较简单。
-
选择Spring Cloud Gateway的原因
接下来讲解为什么选择 Spring Cloud Gateway
作为服务网关。
像上述的 Apache
、Nginx
、OpenResty
、Kong
等产品,功能非常强大,也能够提供网关的功能。它们不仅是网关,还能提供正向代理、反向代理、HTTP
服务器、负载均衡等功能,网关只是其中一个可供使用的功能。这些产品也根本不是单纯为了微服务架构才出现的,甚至早在微服务架构出现之前就已经获得了业内的普遍认可,在各自领域都非常成功,市场占有率也非常高。除作为网关使用外,它们主要作为 Web
服务器使用,提供负载均衡等功能,网关只是它们的 “副业”。
Netflix Zuul
、Spring Cloud Gateway
这两个组件都是细分领域下的一个产品。与上述几种产品相比,不论是性能还是提供的功能都有差距,并不是一个量级的。更准确地说,Netflix Zuul
、Spring Cloud Gateway
就是服务网关,属于微服务架构这个细分领域中的组件,只在一个地方发力,并不是大而全的产品,它们随着 Spring Cloud
解决方案而出现,在微服务架构中扮演着重要的角色。除此之外,在其他应用场景下,它们其实并没有太多 “用武之地”。
前文中给出了一张完整的架构图,不过用户交互层和网络接入层并不是本次微服务实战的重点,由后端开发人员做的工作主要是图 9-6 中的这部分内容。

这里可以确认一点,需要选择的组件是服务网关。而服务网关有 Netflix Zuul
、Spring CloudGateway
这两个组件,答案就非常清晰了。Spring Cloud Gateway
是 Spring Cloud
技术栈中网关组件的首选。同时,Spring Cloud Gateway
十分优秀,Spring Cloud Alibaba
套件中也默认选用该组件作为网关产品,其优点如下。
-
在实际编码和部署时,
Spring Cloud Gateway
可以像其他微服务实例一样来开发和部署。Spring Cloud Gateway
提供了很多特性,而且配置和集成都非常简单,只需要简单配置就能够完成各种复杂的路由逻辑。同时,Spring Cloud Gateway
能够对请求进行统一的处理和拦截,从而完成一些前置处理和功能定制。 -
与其他的微服务实例一样,它会注册到服务中心,这也表明它可以通过服务发现的机制获取服务中心里所需的实例清单。如此一来,
Spring Cloud Gateway
就可以很轻松地根据本地配置的路由,将请求转发到对应的服务实例中。另外,由于服务中心及服务发现机制的存在,当其他微服务实例有增加或删减的情况时,Spring Cloud Gateway
也能够及时获取这些变动,不需要进行额外的配置,就能够实现高伸缩性的目标。
最后,读者可以思考一下,微服务架构中是否一定要使用服务网关呢?服务网关的技术选型是否一定要使用 Spring Cloud Gateway
呢?
通过本文的讲解和分析,读者应该有了自己的答案,按照官方推荐来选择 Spring Cloud Gateway
肯定不会有太多问题。但是,有些读者会说:“我就要选择 OpenResty
来做服务网关。”、“我就是要用 Kong
作为网关模块。” 这些产品笔者都使用过,如果它们确实更适合当前团队和当前的项目,肯定要选择更合适的。如果没有其他原因,按照官方推荐选择 Spring Cloud Gateway
作为服务网关就可以了。