在日常工作中,我们可能都会在不同的场合听到网关的概念,当然通常指的是服务网关(API网关),负责输入输出的API。有了业务网关,各个API服务商可以专注于自己的业务逻辑处理,而API网关则更专注于安全、流量、路由等问题。从功能层面,我们会想到另一个概念——代理。网关和代理的区别:代理的本质是数据的透传,协议不会改变;在数据透传的背景下,网关还会涉及协议转换,比如从HTTP到Dubbo。那么作为架构师,我们应该如何选择“服务网关”呢?我们首先要学会如何进行技术选型,我们期望有一个技术成本预测。比如我推荐使用SpringCloudAlibaba+SpringGateway,这是我作为架构师自己的技术预测。ZuulZuul是Netflix开源的微服务网关,可与Eureka、Ribbon、Hystrix等组件配合使用。SpringCloud对Zuul进行了集成和增强。Zuul有两个大版本:Zuul1.0和Zuul2.0,最新的Zuul版本是v2.2.0,Zuul1.0和Zuul2.0的功能差异非常大。Netflix的Zuul包括以下功能:认证和安全:识别每个资源的验证要求,拒绝那些不符合要求的请求;审查和监控:在边缘跟踪有意义的数据和统计结果;动态路由:动态地将请求路由到不同的后端集群;压力测试:逐渐增加指向集群的流量以了解性能;负载分配:为每种负载类型分配相应的容量,丢弃超过限制值的请求;静态响应处理:直接在边缘建立部分响应,避免转发到内部集群;多区域弹性:跨AWSRegions的请求路由,旨在多样化ELB(ElasticLoadBalancing)的使用,让系统的边缘更接近系统的使用者。以上介绍来自Zuul官方文档,但实际上开源版的Zuul并不具备以上任何功能——开源的Zuul只是几个Jar包,以上能力应该是指的能力Netflix使用的官方Zuul;Netflix使用的Zuul能力更强大,可以使用Groovy写过滤器,可以动态加载/卸载,修改规则,使用Cassandra作为数据库,但是这些开源版本都没有;在SpringCloud中,Zuul的大部分功能由Zuul开发的SpringCloud团队提供;所以Zuul2.x的开源进度推迟了一年。SpringCloud团队开发了自己的SCG,并宣布SpringCloud不打算支持Zuul2.x。你还在惊讶吗?看到这里,可能很多人都没有学习Zuul的动力了。个人觉得还是可以理解的。后面讲SCG的时候,大家会发现很多设计理念是相通的。说完了SpringCloud对Zuul的封装,下面简单分析一下SpringCloud和Zuul的关系。SpringCloud通过SpringCloudNetflix1.X封装了Zuul1.0。1.X最新版本是v1.4.7.RELEASE,对应的Zuul版本是1.3.1。SpringCloudNetflix从3.X开始就没有封装Zuul网关,包括Zuul1.0和Zuul2.0,这意味着开发者想通过SpringCloud复用Zuul只能使用Zuul1.0,暂时不能复用Zuul2.0。Zuul目前在github上有10.2kstar和2kfork,这意味着还有很多开源爱好者会基于Zuul定制业务网关。除了开源的SpringCloud定制的Zuul,开源的微服务框架jhipster也参与定制并融入其生态。Jhipster主要包括generator-jhipster和jhipster-registry。前者星数17.7k,分叉数3.5k。后者的star数为604,fork数为607。Zuul1.0的整体架构设计如图所示。Zuul2.0的整体架构设计如图所示。SpringCloudGatewaySCG是基于SpringFramework5.0和SpringBoot2.0构建的API网关,提供路由等功能。它旨在提供一种简单高效的方式来路由到API,并为它们提供横切关注点,例如:安全性、监控/指标和弹性。主要特点:Java8SpringFramework5SpringBoot2动态路由SpringHandlerMapping内置路由匹配HTTP请求路由匹配(路径、方法、header、host等)FiltersScope匹配路由Filters可以修改下游HTTP请求和HTTP响应(add、method、header、host等)DeleteHeader,add/deleteparameters,rewritepath,setpath等)API或configurationdriver支持SpringCloudDiscoveryClient配置路由SCG术语包括:路由:是基本的构建块,主要包括ID,URI、断言集合和过滤器的集合,如果匹配断言将执行路由。断言:主要是指Java8的功能断言。输入类型是SpringFramework的ServerWebExchange。基于断言,它可以根据标头或参数匹配HTTP请求。Filter:是基于SpringFrameworkGatewayFilter,通过特殊的工厂方法构造的实现。通过filterdeveloper可以在HTTP请求下山前修改请求响应参数,在请求响应返回后修改响应结果。SCG的整体架构设计如图所示。自研网关API网关的基本功能包括统一接入、协议适配、流量控制与容错、安全防护等。这四大基本功能构成了网关的核心能力。网关的主要功能是负责统一接入,然后将请求的协议转换成内部接口协议。在调用过程中,需要通过限流、降级、熔断等容错方式来保护网关的整体稳定性。同时,网关还需要实现基础安全防护(防刷控),以及黑白名单(如IP地址白名单)等基础安全措施,主要包括:统一标准接入、高性能、高并发高可靠,负载均衡能力强;除了基本的四个功能,网关运行良好的环境还包括注册中心(比如通过Nacos读取发布的API接口的动态配置)。为了达到高性能,所有的数据都异构存储在缓存中(如Redis),也可以配合本地缓存进一步提升网关系统的性能。为了提高网关的吞吐率,可以采用NIO+Servlet3的异步方式,也可以利用Servlet3的异步特性,将请求线程与业务处理线程分离,为后续的线程池隔离提供基础支持。访问日志的存储可以存储在Hbase或者ES中。如果要用作开放网关,则需要支持OAuth2.0协议的授权中心。同时可以引入Nginx+Lua,将一些基本的验证判断放到应用系统上,让网关接入的问题处理得更轻量级。主要包括接入层。开发者可以使用Nginx和Lua脚本来解决限流、黑白名单、路由、负载均衡、长短连接、容灾切换等问题。网关需要保证服务的稳定性,需要连接到注册中心。由于本书是SpringCloudAlibaba的布道书,强烈推荐使用Nacos作为注册中心和配置中心。统一认证中心主要解决网关统一服务于各种API的认证问题。当然也可以根据业务维度进行隔离,自定义认证规则。统一用户中心主要是为了解决用户登录的问题,保证微服务调用的安全。自研网关还需要具备泛化功能。用户调用提供者的接口时,不再需要API提供者的客户端JAR包,所以没有POJO,通过泛化实现远程调用。一般我们想通过RPC调用接口提供者的服务,首先在系统中嵌入接口提供者的JAR包,然后使用JAR包中的类和方法。对于一个网关系统,如果要调用N个接口,就需要N个JAR包。这样的网关很难维护。当然,DubboRPC是支持泛化的。网关必须具备时间验证、方法验证、版本验证、签名验证等功能。当然,网关还需要具备服务降级、日志记录、监控告警等功能。对比以上三种网关网关限流和鉴权监控易用性可维护性成熟度SCG可通过IP、用户和集群限流提供相应接口进行扩展通用鉴权auth2.0GatewayMetricsFilter易用Spring系列扩展性强,配置简单可维护性好Spring社区成熟,但Gateway资源少。Zuul2可以通过配置文件配置集群限流和单机限流,也可以通过过滤器实现限流。展开过滤器以实现过滤器中的实现。参考资料相对较少,可维护性较差,开源意味着资源较少。Zuul1DittoDittoDittoDittoDittoDittoDittoDitto同上自研网关需要开发需要开发需要开发需要开发需要开发需要开发需要开发需要开发需要开发需要开发需要开发需要开发需要开发需要开发需要开发开发需要开发需要开发需要开发需要开发需要开发高可维护性需要开发总结推荐使用SpringCloudAlibaba+SpringCloudGateway,可以更高效的利用SpringCloudAlibaba的服务治理能力,集成GatewayAPI的Governance,从而提高业务服务API的系统稳定性。
