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

posted @ 2024-06-29 14:33  欢乐豆123  阅读(31)  评论(0编辑  收藏  举报