SpringCloud微服务系列- 分布式能力建设之微服务网关
SpringCloud微服务系列- 分布式能力建设之微服务网关
概要
在微服务环境中,网关是微服务集群中必不可少的设施之一。
微服务中网关的首要职责,就是以统一的地址对外提供服务,将外部访问这个地址的流量,根据适当的规则路由到内部集群中正确的服务节点之上。也正是因为这样,微服务中的网关,也常被称为“服务网关”或者“API 网关”。
网关 = 路由器(基础职能) + 过滤器(可选职能)
一、什么是网关
API网关是一个服务器,是系统的唯一入口。 从面向对象设计的角度看,它与外观模式类似。
API网关封装了系统内部架构,为每个客户端提供一个定制的API。它可能还具有其它职责,如身份验证、监控、负载均衡、缓存、协议转换、限流熔断、静态响应处理。
API网关方式的核心要点是,所有的客户端和消费端都通过统一的网关接入微服务,在网关层处理所有的非业务功能。通常,网关也是提供REST/HTTP的访问API。
二、为什么需要服务网关
服务网关有以下功能:
- 性能:API高可用,负载均衡,容错机制。
- 安全:权限身份认证、脱敏,流量清洗,后端签名(保证全链路可信调用),黑名单(非法调用的限制)。
- 日志:日志记录(spainid,traceid)一旦涉及分布式,全链路跟踪必不可少。
- 缓存:数据缓存。
- 监控:记录请求响应数据,api耗时分析,性能监控。
- 限流:流量控制,错峰流控,可以定义多种限流规则。
- 灰度:线上灰度部署,可以减小风险。
- 路由:动态路由规则。
一个简单的微服务架构大致如下图:
三、服务网关的3个核心概念
服务网关的核心概念有:路由、断言、过滤
1. 路由(Route)
路由是Gateway的一个基本单元。每一个路由都有一个目标服务地址。
它由一个ID、一个目标URI、一组断言和一组过滤器定义。如果断言为真,则路由匹配。
当一个请求到达Spring Cloud Gateway时,它的处理顺序是:predicates -> uri -> filters
- predicates负责路由的配置断言,它可以通过PredicateDefinition类进行配置
- uri则是匹配路由的转发地址,当predicates匹配成功后,URI则确定了请求的具体处理地址。
- 过滤器(Filter)则是对路由的处理过程进行额外的操作,例如添加、删除或修改请求头等。这些过滤器可以对请求和响应进行处理
1)普通路由
yml配置如下:
1 server: 2 port: 9527 3 spring: 4 cloud: 5 gateway: 6 # 路由配置 7 routes: 8 # http://Localhost/order/index 9 # 路由id没有具体规则要求 但是有一个点唯一 10 - id: cloud-order-consumer 11 # 目标服务地址 12 uri: http://localhost:80 13 # 路由条件断言会接收一个输入参数,返回一个布尔结果值 14 # http://Localhost:9527/order/index 15 predicates: 16 - Path=/order/*
2)动态路由
默认情况下Gateways会根据注册中心的服务列表,以注册中心上微服务名为路径创建动态路由进行转发,从而实现动态路由的功能
yml配置如下:
1 server: 2 port: 9528 3 eureka: 4 client: 5 service-url: 6 # 单机eureka 服务 地址 7 #defaultZone: http://localhost:7001/eureka/ 8 defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/ 9 instance: 10 instance-id: cloud-gateway-gateway9528 11 12 spring: 13 application: 14 # 设置应用名字 15 name: cloud-gateway 16 cloud: 17 gateway: 18 # 路由配置 19 routes: 20 # http://Localhost/order/index 21 # 路由id没有具体规则要求 但是有一个点唯一 22 - id: cloud-provider-payment 23 # 目标服务地址lb 后面是微服务名字 lb(loadbalancer) 24 uri: lb://CLOUD-PAYMENT-PROVIDER 25 # 路由条件断言会接收一个输入参数,返回一个布尔结果值 26 # http://Localhost:9527/payment/db 27 predicates: 28 - Path=/payment/*
2. 断言(predicate)
一个请求在抵达网关层后,首先就要进行断言匹配,在满足所有断言之后才会进入Filter阶段。
说白了Predicate就是一种路由规则,通过Gateway中丰富的内置断言的组合,我们就能让一个请求找到对应的Route来处理。
下面是application.yml中的断言配置:
1 spring: 2 application: 3 # 设置应用名字 4 name: cloud-gateway 5 cloud: 6 gateway: 7 # 路由配置 8 routes: 9 # http://Localhost/order/index 10 # 路由id没有具体规则要求 但是有一个点唯一 11 - id: cloud-provider-payment 12 # 目标服务地址lb 后面是微服务名字 lb(loadbalancer) 13 uri: lb://CLOUD-PAYMENT-PROVIDER 14 # 路由条件断言会接收一个输入参数,返回一个布尔结果值 15 # http://Localhost:9527/payment/db 16 predicates: 17 - Path=/payment/* 18 #- After=2030-02-15T14:54:23.317+08:00[Asia/Shanghai] 19 #- Before=2030-02-15T14:54:23.317+08:00[Asia/Shanghai] 20 #- Between=2024-06-15T14:54:23.317+08:00[Asia/Shanghai],2030-02-15T14:54:23.317+08:00[Asia/Shanghai] 21 #- Cookie=username,zzyy 22 #- Header=X-Request-Id,\d+ 23 #- Host=itbaizhan 24 #- Method=GET 25 #- Query=username,\d+ 26 filters: 27 #- SetStatus=250 28 - Log=true
1)After路由断言Factory
After Route Predicate Factory采用一个参数一一日期时间。在该日期时间之后发生的请求都将被匹配。
应用场景:商城整点秒杀,某个接口在某个时间后才能用
注意:时间参数的格式为UTC。
UTC时间格式的时间参数时间生成方法如下:
1 public static void main(string[]args){ 2 3 ZonedDateTime now ZonedDateTime.now(); 4 5 System.out.printlIn(now); 6 7 }
2) Before路由断言Factory
Before Route Predicate Factory采用一个参数一一日期时间。在该日期时间之前发生的请求都将被匹配。
应用场景:商城中某些特价商品,超过了某个时间接口不能用
3) Between路由断言Factory
Between路由断言Factory有两个参数,datetime1和datetime2。在datetime1和datetime2之间的请求将被匹配。datetime2参数的实际时间必须在datetime1之后。
4) Cookiei路由断言Factory
顾名思义,Cookie验证的是Cookie中保存的信息,Cookiel断言和上面介绍的两种断言使用方式大同小异,唯一的不同是它必须连同属性值一同验证,
不能单独只验证属性是否存在。
5) Headeri路由断言Factory
这个断言会检查Header中是否包含了响应的属性,通常可以用来验证请求是否携带了访问令牌。
6) Host路由断言Factory(使用相对较少)
Host路由断言Factory包括一个参数:host name列表。使用Ant路径匹配规则。.作为分隔符。访问的主机匹配http或者https,,baidu.com默认80端口,
就可以通过路由。多个,号隔开。
说明:通过域名进行断言
7) Method路由断言Factory
这个断言是专门验证HTTP Method的,在下面的例子中,我们把Method断言和Path断言通过一个and连接符合并起来,共同作用于路由判断,当我们访问"/gateway/sample"并且 HTTP Method是GET的时候,将适配下面的路由。
8) Query路由断言Factory
请求断言也是在业务中经常使用的,它会从ServerHttpRequest中的Parameters列表中查询指定的属性,有如下两种不同的使用方式。
3. 过滤(filter)
可以在请求被路由前或者之后对请求进行修改。
微服务系统中的服务非常多。如果每个服务都自己做鉴权、限流、日志输出,则非常不科学。所以,可以通过网关的过滤器来处理这些工作。在用户访问各个服务前,应在网关层统一做好鉴权、限流等工作。
1) Filter的生命周期
根据生命周期可以将Spring Cloud Gateway中的Filter分为"PRE"和"POST"两种。
PRE:代表在请求被路由之前执行该过滤器,此种过滤器可用来实现参数校验、权限校验、流量监控、日志输出、协议转换等功能。
POST:代表在请求被路由到微服务之后执行该过滤器。此种过滤器可用来实现响应头的修改(如添加标准的HTTP Header)、收集统计信息和指标、将响应发送给客户端,输出日志、流量监控等功能。
2)Filter分类
根据作用范围,Filter可以分为以下两种:
- GatewayFilter: 网关过滤器,此种过滤器只应用在单个路由或者一个分组的路由上。
- GlobalFilter: 全局过滤器,此种过滤器会应用在所有的路由上。
参考链接:
https://juejin.cn/post/7010229077797765150