微服务平台之网关架构与应用

2020-06-09 11:25:41 浏览数 (1)

转载本文需注明出处:微信公众号EAWorld,违者必究。

前言:

API 网关出现的原因是微服务架构的出现,不同的微服务一般会有不同的网络地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与各个微服务通信,会有以下的问题:

1、客户端会多次请求不同的微服务,增加了客户端的复杂性。

2、存在跨域请求,在一定场景下处理相对复杂。

3、认证复杂,每个服务都需要独立认证。

4、难以重构,随着项目的迭代,可能需要重新划分微服务。例如,可能将多个服务合并成一个或者将一个服务拆分成多个。如果客户端直接与微服务通信,那么重构将会很难实施。

5、某些微服务可能使用了防火墙 / 浏览器不友好的协议,直接访问会有一定的困难。

以上这些问题可以借助 API 网关解决。API 网关是介于客户端和服务器端之间的中间层,所有的外部请求都会先经过 API 网关这一层。也就是说,网关的角色是作为一个 API 架构,用来保护、增强和控制对于 API 服务的访问。

目录:

1、API网关的定义

2、为什么选择Gateway

3、部分Predicate的实现

4、普元EOS 8 网关架构

5、普元EOS 8 网关应用

6、未来展望

1.API网关的定义

网关的角色是作为一个 API 架构,用来保护、增强和控制对于 API 服务的访问。API 网关是一个处于应用程序或服务(提供 REST API 接口服务)之前的系统,用来管理授权、访问控制和流量限制等,这样 REST API 接口服务就被 API 网关保护起来,对所有的调用者透明。因此,隐藏在 API 网关后面的业务系统就可以专注于创建和管理服务,而不用去处理这些策略性的基础设施。

网关的职能

  1. 请求接入:作为所有API接口服务请求的接入点。
  2. 业务聚合:作为所有后端业务服务的聚合点。
  3. 中介策略:实现安全,验证,路由,过滤等策略。
  4. 统一管理:对所有API服务和策略进行统一管理。

主要功能

主要功能大致分为稳定与安全,提供更好的服务两方面:

稳定与安全:

  1. 全局性流控
  2. 日志统计
  3. 防止SQL注入
  4. 防止Web攻击
  5. 屏蔽工具扫描
  6. 黑白IP名单
  7. 证书/加密处理

提供更好的服务:

  1. 服务级别流控
  2. 服务降级与熔断
  3. 路由与负载均衡,灰度策略
  4. 服务过滤,聚合发现
  5. 权限验证与用户等级策略
  6. 业务规则与参数校验
  7. 多级缓存策略

2.为什么选择Gateway

Spring Cloud Gateway 可以看做是一个 Zuul 1.x 的升级版和代替品,比 Zuul 2 更早的使用 Netty 实现异步 IO,从而实现了一个简单、比 Zuul 1.x 更高效的、与 Spring Cloud 紧密配合的 API 网关。

Spring Cloud Gateway 里明确的区分了 Router 和 Filter,并且一个很大的特点是内置了非常多的开箱即用功能,并且都可以通过 SpringBoot 配置或者手工编码链式调用来使用。

比如内置了 10 种 Router,使得我们可以直接配置一下就可以随心所欲的根据 Header、或者 Path、或者 Host、或者 Query 来做路由。

比如区分了一般的 Filter 和全局 Filter,内置了 20 种 Filter 和 9 种全局 Filter,也都可以直接用。当然自定义 Filter 也非常方便。

几个重要概念:

路由:Gateway的基础构建模块。它包括一个ID,一个目标URL,一个断言集合和一个过滤器集合。如果断言判断为真,则路由匹配。

断言:这是Java8的新增功能,输入的类型为Spring框架的ServerWebExchange。它可以匹配HTTP请求中的任何东西,比如:请求头或者参数。

过滤器:是Spring框架的GatewayFilter,请求和响应都可以被Filter修改。

3.部分Predicate的实现

Predicate 来源于 Java 8,是 Java 8 中引入的一个函数,Predicate 接受一个输入参数,返回一个布尔值结果。该接口包含多种默认方法来将 Predicate 组合成其他复杂的逻辑(比如:与,或,非)。可以用于接口请求参数校验、判断新老数据是否有变化需要进行更新操作。

在 Spring Cloud Gateway 中 Spring 利用 Predicate 的特性实现了各种路由匹配规则,有通过 Header、请求参数等不同的条件来进行作为条件匹配到对应的路由。

这边就列举几个匹配的转发实例:

1、通过时间匹配

Predicate 支持设置一个时间,在请求进行转发的时候,可以通过判断在这个时间之前或者之后进行转发。比如我们现在设置只有在 2020 年 1 月 1 日才会转发到我的网站,在这之前不进行转发,我就可以这样配置:

Spring 是通过 ZonedDateTime 来对时间进行的对比,ZonedDateTime 是 Java 8 中日期时间功能里,用于表示带时区的日期与时间信息的类,ZonedDateTime 支持通过时区来设置时间,中国的时区是:Asia/Shanghai。

After Route Predicate 是指在这个时间之后的请求都转发到目标地址。上面的示例是指,请求时间在 2020 年 1 月1 日 6 点之后的所有请求都转发到地址http://www.primeton.com。 08:00是指时间和 UTC 时间相差八个小时,时间地区为Asia/Shanghai。添加完路由规则之后,访问地址http://网关IP:PORT会自动转发到http:// www.primeton.com。

Before Route Predicate 刚好相反,在某个时间之前的请求的请求都进行转发。我们把上面路由规则中的 After 改为 Before,如下:

就表示在这个时间之前可以进行路由,在这时间之后停止路由,修改完之后重启项目再次访问地址http://网关IP:PORT,页面会报 404 没有找到地址。

在时间之前或者之后外,Gateway 还支持限制路由请求在某一个时间段范围内,可以使用 Between Route Predicate 来实现:

2、通过 Cookie 匹配

Cookie Route Predicate 可以接收两个参数,一个是 Cookie name , 一个是正则表达式,路由规则会通过获取对应的 Cookie name 值和正则表达式去匹配,如果匹配上就会执行路由,如果没有匹配上则不执行。

使用 curl 测试,命令行输入:

则会返回页面代码,如果去掉--cookie "primeton=eos.primeton",后台会提示 404 错误

Header Route Predicate 和 Cookie Route Predicate 一样,也是接收 2 个参数,一个 header 中属性名称和一个正则表达式,这个属性值和正则表达式匹配则执行。

使用 curl 测试,命令行输入:

则返回页面代码证明匹配成功。将参数-H "X-Request-Id:88888"改为-H "X-Request-Id:zero"再次执行时返回 404 证明没有匹配。

3、通过 Host 匹配

Host Route Predicate 接收一组参数,一组匹配的域名列表,这个模板是一个 ant 分隔的模板,用.号作为分隔符。它通过参数中的主机地址作为匹配规则。

使用 curl 测试,命令行输入:

经测试以上两种 host 均可匹配到 host_route 路由,去掉 host 参数则会报 404 错误。

4.普元EOS 8网关架构

EOS 8网关架构图

1. 在微服务治理平台中, 一个系统将部署一套网关。系统内部应用的前端访问后端, 或者其它系统的应用需要访问此系统内的应用提供的接口, 请求必须走网关。

2. 网关对外提供治理数据的 rest 接口, 治理平台通过此接口将治理数据发送至网关。

3. 网关可以部署多个对等实例, 以扩充其性能。

4. 网关收到治理数据之后, 由统一存储接口保持至持久存储之中,然后由存储的通知机制,通知所有网关实例。

5. 为了提升性能,避免频繁从持久存储中查询数据,网关内部设计了基于内存的高速缓存。它们在网关启动时,将自动从持久存储加载治理数据。

6. 网关缓存也支持通过懒加载的方式, 按需加载所需治理数据。

7. 经历各filter之后, 请求发往应用的哪些实例, 将在 LBPredicate 之中决定, 它会根据请求头中带的应用实例组编码对应用实例进行过滤。

8. EOS8的网关将不在和Coframe共用一个持久化存储,转而使用应用自己本身的存储,大大降低接入成本。

9. 认证业务插件化改造,只需实现网关提供的认证接口,即可快速完成认证和鉴权,用户也可以逐步实现按需扩展的需求。

EOS 8网关设计要点

1. EOS8的网关将不在和Coframe共用一个持久化存储,转而使用应用自己本身的存储,大大降低接入成本。

2. 认证业务插件化改造,只需实现网关提供的认证接口,即可快速完成认证和鉴权,用户也可以逐步实现按需扩展的需求。

实现细节

1. 创建插件项目

项目名称格式建议以gateway-plugin- 开头, 如 gateway-plugin-handle-eos8

为了统一第三方jar包依赖, 防止版本冲突, 项目父pom必须为网关的pom

2. 实现gateway-core中的UserService接口

参数说明:

3. 插件构建与部署

在插件的pom中, 需要添加构建相关的配置

网关的部署介质结构如下:

EOS_Microservices_API_Gateway/

├── bin

│ ├── shutdown.sh

│ └── startup.sh

├── config

│ ├── application.yml

│ └── logback-spring.xml

├── gateway-boot-5.0.0-GA-SNAPSHOT.jar

├── lib

│ └── plugins

│ └── gateway-plugin-handle-eos8 -8.1.0-LA-SNAPSHOT.jar

└── logs

├── eos-dap-gateway

│ └── eos-dap-gateway.pid

├── eos-dap-gateway.out

├── gateway.log

└── gateway-trace.log

插件构建成jar包之后, 需要将其复制至lib/plugins目录之下, 然后重启网关。

5.普元EOS 8网关应用

为了方便用户更好的理解和使用我们的EOS8网关,在EOS8的Governor平台中,提供了一整套的可视化操作。

主要分为网关详情,白名单配置,API发布和授权(针对跨系统访问),路由,日志,统计查询,Top查询等功能

1. 白名单配置

网关上线后,如果开启了token有效性验证,根据自己的业务需要可以配置放行的白名单(配置了路由转发的情况下,白名单的请求接口也需要添加对应的url前缀)

2. API发布与授权

同系统的网关调用,只需要请求头中的X-EOS-SourceSysKey与当前系统凭证一致即可,并不需要进行API发布与授权

当本系统的中的接口需要被其他系统调用的时候,就需要用到API发布和API授权功能

  1. Governor会自动读取系统内所有对外的EOS服务接口,点击已发布后,进入API授权功能
  2. 新增指定的订阅者后,将刚发发布的接口进行授权,即可完成API授权功能
  3. 在调用者一边,创建一个实体类实现SDKApiSubscriberProvider接口即可

3.路由配置

在路由配置界面,我们提供了可视化的路由配置功能,并且提供三种不同的路由模板,方便用户快速完成路由的配置。

4. 日志查询

网关运行后,所有系统日志均可在日志页面进行查询。

5. 统计查询

所有经过的网关的请求都会被记录并且生成统计,方便日后的定位与分析。

6. TOP查询

我们还会对请求数,平均响应时间,错误数,错误率进行TOP查询,方便用户准确定位和及时跟踪。

6.未来展望

1. 通过我们的规则制定,在插件中, 可以为网关添加各种 RoutePredicateFactory, GatewayFilterFactory, Filter, Predicate 等, 扩充网关在路由匹配, 请求过滤, 负载均衡等各方面的能力,支持各种个性化的改造。

2. 在Governor的网关管理界面,提供整套的网关插件管理功能。

3. 同时可以实现高效的插件热部署。

以上就是我为大家带来的EOS服务网关架构的介绍,希望对大家有所帮助,如有不足之处也请多多指教,谢谢。

精选提问:

问1:有没有针对springcloudgateway网关的监控和运维(如启停)功能啊?

答:我们现在governor上的网关功能就是针对springcloudgateway做的监控和运维,不过需要从我们的介质库中获取网关介质,第三方接入的,部分功能会有缺失,例如流控,可视化管理等。

问2:新发布API或者Filter如何做到不重启网关?

答:新发布API是通过我们governor的统一配置中心进行热部署推送,可以做到实时性,filter暂时还只能通过重启的方式解决,但是在下个版本,应该也可以做到。

问3:网关的负载均衡如何理解?是有集群吗?

答:GateWay也可以实现负载均衡的能力是通过服务注册中心的服务名/接口实现负载均衡的能力。

问4:微服务是否是一个系统部署一个网关?

答:在goveror的系统中,一个系统只能部署一个网关,但是网关可以有多个实例(可以理解成集群部署)。

问5:EOS 8是基于spring cloud gateway 开发的吗?如果是,用的什么版本?

答:EOS是基于spring cloud gateway 2.12的版本上开发的。

问6:如何保证网关高可靠性?

答:Spring Cloud Gateway建立在Spring Framework 5,Project Reactor和Spring Boot 2之上,使用非阻塞API,并且它与Spring紧密集成,使他在微服务体系中的可靠性得到了保证。

问7:Spring Cloud Gateway 没有内嵌tomcat了吧,直接使用nettty处理请求和响应。

答:gateway用的是netty框架,在某些场合使用 gateway 还要排除netflix-eureka中的tomcat容器。

关于作者:喜羊羊,普元EOS8项目高级软件工程师,主要负责Governor,Coframe,网关等项目的设计与开发工作。曾参与白玉兰远程教网、NSS次期收纳系统等多个大型项目。我是革命一块砖,哪里需要往哪搬,我是发展一朵花,哪里能开往哪插。

0 人点赞