转载本文需注明出处:微信公众号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 网关后面的业务系统就可以专注于创建和管理服务,而不用去处理这些策略性的基础设施。
网关的职能
- 请求接入:作为所有API接口服务请求的接入点。
- 业务聚合:作为所有后端业务服务的聚合点。
- 中介策略:实现安全,验证,路由,过滤等策略。
- 统一管理:对所有API服务和策略进行统一管理。
主要功能
主要功能大致分为稳定与安全,提供更好的服务两方面:
稳定与安全:
- 全局性流控
- 日志统计
- 防止SQL注入
- 防止Web攻击
- 屏蔽工具扫描
- 黑白IP名单
- 证书/加密处理
提供更好的服务:
- 服务级别流控
- 服务降级与熔断
- 路由与负载均衡,灰度策略
- 服务过滤,聚合发现
- 权限验证与用户等级策略
- 业务规则与参数校验
- 多级缓存策略
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授权功能
- Governor会自动读取系统内所有对外的EOS服务接口,点击已发布后,进入API授权功能
- 新增指定的订阅者后,将刚发发布的接口进行授权,即可完成API授权功能
- 在调用者一边,创建一个实体类实现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次期收纳系统等多个大型项目。我是革命一块砖,哪里需要往哪搬,我是发展一朵花,哪里能开往哪插。