网关全是0代表着什么_SpringCloudGateway---微服务网关

ce259f1b220f466c8d012a6a84daf87d.png

【微服务网关SpringCloudGateway】

主要内容

  1. API网关
  2. Spring Cloud Gateway简介
  3. Spring Cloud Gateway路由
  4. Spring Cloud Gateway谓词
  5. Spring Cloud Gateway过滤器
  6. Spring Cloud Gateway熔断

一、API网关

1. 什么是API网关

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

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

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

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

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

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

以上这些问题可以借助 API 网关解决。API 网关是介于客户端和服务器端之间的中间层,所有的外部请求都会先经过 API 网关这一层。也就是说,API 的实现方面更多的考虑业务逻辑,而安全、性能、监控可以交由 API 网关来做,这样既提高业务灵活性又不缺安全性。

使用API网关后示意图:

3931297d6ca1f9f117d9b784c3c8c6e3.png

使用 API 网关后的优点如下:

易于监控。可以在网关收集监控数据并将其推送到外部系统进行分析。

易于认证。可以在网关上进行认证,然后再将请求转发到后端的微服务,而无须在每个微服务中进行认证。

统一接入。减少了客户端与各个微服务之间的交互次数。

1.1 路由

路由是网关最基础的部分,路由信息有一个ID、一个目的URL、一组断言和一组Filter组成。如果断言路由为真,则说明请求的URL和配置匹配。

1.2 过滤器

网关非常重要的功能就是过滤器。可以把微服务中很多公共的功能都提出到网关的过滤器中,这样就可以实现复用。如:认证功能、权限校验功能等。

由于网关是统一的入口,所以还可以在网关中实现一些记录或容错等逻辑实现。例如限流、监控、熔断、协议转换、日志等。

一个标准的Spring webFilter。Spring cloud gateway中的filter分为两种类型的Filter,分别是Gateway Filter和Global Filter。过滤器Filter将会对请求和响应进行修改处理。

2. Spring Cloud中提供的网关解决方案

2.1 Spring Cloud Netflix Zuul

属于Spring Cloud Netflix下一个组件,具有灵活、简单的特点。在早期Spring Cloud中使用的比较多。

其版本更新都依赖于Netflix Zuul。

2.2 Spring Cloud Gateway

由Spring 自己推出的网关产品,完全依赖Spring自家产品。符合Spring战略意义,其更新版本等都由Spring自己把控。

目前很多项目中都是使用Gateway替代Zuul。

在本套课程中讲解的也是Gateway

二、Spring Cloud Gateway

1. 简介

Spring cloud gateway是spring官方基于Spring 5.0、Spring Boot2.0和Project Reactor等技术开发的网关,Spring Cloud Gateway旨在为微服务架构提供简单、有效和统一的API路由管理方式,Spring Cloud Gateway作为Spring Cloud生态系统中的网关,目标是替代Netflix Zuul,其不仅提供统一的路由方式,并且还基于Filer链的方式提供了网关基本的功能,例如:安全、监控/埋点、限流等。

2. 名词解释

2.1 Route

Route中文称为路由,Gateway里面的Route是主要学习内容。

一个路由包含ID、URI、Predicate集合、Filter集合。

在Route中ID是自定的,URI就是一个地址。剩下的Predicate和Filter学习明白了,Route就学习清楚了。

2.2 Predicate

中文:谓词。

谓词时学习Gateway比较重要的一点,简单点理解谓词就是一些附加条件和内容。

2.3 Filter

所有生效的Filter都是GatewayFilter的实例。在Gateway运行过程中Filter负责在代理服务“之前”或“之后”去做一些事情。

3. 流程

5b7431407b682356ba20dd989b9b0677.png

3.1 解释

当Gateway接收到外界请求后,如果Gateway Handler Mapping确认请求与路由匹配(Gateway可以包含多个Route),交给Gateway Web Handler 。之后交给特定的Filter 链进行处理,整个Filter 链的前置(pre)被执行后,执行代理的服务(Proxied Service),最后执行Filter 链的post部分。返回给Gateway Web Handler,在返回给Gateway Web Handler Mapping,最终返回给客户端。

三、使用Spring Cloud Gateway实现路由功能

1. 入门案例

Gateway网关,在默认环境下,可以通过服务名称实现网关路由功能。如:

现有微服务 - 服务名为: feign-app-service, 启动gateway网关后,请求地址为: http://gatewayIP:gatewayPort/feign-app-service/index, 可以实现访问feign-app-service微服务的/index控制器方法。

1.1 创建Gateway项目

bd80dbc08792f63a09e0abdcbf970d19.png

1)POM文件

<?xml version="1.0" encoding="UTF-8"?>

2)配置文件

server:
  port: 9000
spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true  # 开启Gateway服务注册和发现的功能
          lower-case-service-id: true  # 将请求路径上的服务名配置为小写
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

3)启动类

package 

2. 配置文件手工绑定路由规则

2.1 POM文件

不需要修改。

2.2 配置文件

server:
  port: 9000
spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: false  # 开启Gateway自动服务注册和发现的功能
          lower-case-service-id: true  # 将请求路径上的服务名配置为小写
      routes:
        - id: openfeign-client # 唯一命名,不重复即可,无其他要求
          uri: lb://openfeign-client # 转发路径,lb代表loadbalance,即从Eureka中获取的服务列表负载均衡器。 openfeign-client即服务名称,相当于http://localhost:8082/
          predicates: # 定义映射
            - Path=/client/**  # 发送到Gateway网关上的请求路径映射,此映射匹配的路径都会转发到uri上。 具体地址为: lb://openfeign-client/client/**
          filters:
            - StripPrefix=1 # 请求转发时,会自动过滤请求转发的第一节地址,即client。最终地址为: lb://openfeign-client/**
        - id: openfeign-service
          uri: lb://openfeign-service
          predicates:
            - Path=/service/**
          filters:
            - StripPrefix=1

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

2.3 启动类

不需要修改。

四、Predicate谓词

谓词:当满足条件在进行路由转发。

在Spring Cloud Gateway中谓词实现GatewayPredicate接口。其中类名符合:XXXRoutePredicateFactory,其中XXX就是在配置文件中谓词名称。在上面示例中Path=/demo/** 实际上使用的就是PathRoutePredicateFactory

ad5f2638dc7ebe5e7d0635c54c4a7087.png

所有的谓词都设置在predicates属性中,当设置多个谓词时取逻辑与条件,且一个谓词只能设置一组条件,如果需要有个多条件,添加多个相同谓词。

所有的Predicate都可以通过源码查看属性赋值的方式。查看方式为:

看类型中的Config内部类,

如:PathRoutPredicateFactory中

e92d2cac9faeed7947aee625546479a0.png

根据内部类的属性,来确认赋值数据的方式。如:PathRoutePredicateFactory中内部类Config的属性是List<String>类型的,那么赋值的时候,就是Path=a,b,c,d,使用逗号分隔多个值即可。

如:QueryRoutePredicateFactory中

e4fed171378575c17063f5757ec36439.png

有多个属性,param和regexp,都是字符串类型的。那么赋值的时候,必须是:Query=param属性的值[,regexp属性的值],因为属性param上有注解NotEmpty,代表此属性必须赋值,regexp属性没有这个赋值,则可选赋值。

1 Query

1.1 设置必须包含的参数名。

下面两种写法等效。都表示路径满足/demo/**同时包含参数abc。

Path和Query是谓词。abc是请求参数名称。

在浏览器中输入:http://localhost:9000/demo/one?abc=jqk

bd883362f2ec09f1d8a7e55d6cce2dd3.png

1.2 设置参数的值

abc请求参数名称。jqk. 是abc的值,是一个正则表达式。在正则表达式中点(.)表示匹配任意一个字符。所以当请求参数abc=jqka或abc=jqkw能满足谓词条件。

在谓词中赋值使用逗号(,)赋值因为Query后面已经有等号,在值内容中在出现等号语法说不过去了。

ed341cd4aa579e812ba942ec5e78b224.png

2. Header

表示请求头中必须包含的内容。

注意:

参数名和参数值之间依然使用逗号

参数值要使用正则表达式

如果Header只有一个值表示请求头中必须包含的参数。如果有两个值,第一个表示请求头必须包含的参数名,第二个表示请求头参数对应值。

9d6bd368b473269d85f604bfb19df899.png

如果设定请求头中需要包含多个参数及值。设置多个Header。在此处演示多个相同谓词配置,其他谓词中就不在强调可以配置多个谓词。

18e31ffd20126a10f699d67a87a90407.png

3. Method

Method表示请求方式。支持多个值,使用逗号分隔,多个值之间为or条件。

47247f4ad80c544b887e2189a1eaaddc.png

4. RemoteAddr

允许访问的客户端地址。

要注意使用127.0.0.1而不要使用localhost。

d29a6d96b95997936bb95ae1d4196191.png

5. Weight

负载均衡中权重。同一个组中URI进行负载均衡。

语法:Weight=组名,负载均衡权重

在Eureka中注册两个服务,这个服务(项目)是相同的,应用程序名分别叫做demo-one和demo-two。

Gateway在路由匹配时demo-one将占20%,demo-two将占80%

5f5bdefed18eddb805f43722477347b2.png

6. Host

匹配请求参数中Host参数的值。满足Ant模式(之前在Spring Security中学习过)可以使用

? 匹配一个字符

* 匹配0个或多个字符

** 匹配0个或多个目录

68f65f11bc60b972c67757ac3319a49a.png

7. Cookie

要求请求中包含指定Cookie名和满足特定正则要求的值。

Cookie必须有两个值,第一个Cookie包含的参数名,第二个表示参数对应的值,正则表达式。不支持一个参数写法。

f72f88ebcd93903a7d1ea1b3f272c0e5.png

8. Between

请求时必须在设定的时间范围内容,才进行路由转发。

注意:时间的格式

e4503fb4334f5b5e6d71636f1dd32390.png

9. Before

在指定时间点之前

0575d16bf3202fcbb5d8581c16c77ac6.png

10. After

在指定时间点之后

d415b12368b1e3abc28811f8f5ca4478.png

五、使用Spring Cloud Gateway实现过滤器功能

Spring Cloud Gateway的filter分为两种:GatewayFilter和GlobalFilter。GlobalFilter会应用到所有的路由上,而Gatewayfilter将应用到单个路由或者一个分组的路由上。

多个过滤器会根据配置文件中的定义来决定执行顺序。

如果提供的自定义过滤器实现了Ordered接口,则可以通过接口中的方法getOrder来决定执行顺序。具体顺序由getOrder方法返回结果升序排列。

1. Spring Cloud Gateway内置过滤器

GatewayFilter是一个接口,通过查看源码,其有很多实现类,不同的实现类实现不同的过滤功能。具体如下:

0863fdd598a331245e1e7b795e2fc13e.png

常用过滤器有:

  • ① AddRequestParameterGatewayFilterFactory - 在指定请求中增加请求参数的过滤器。
  • ② AddRequestHeaderGatewayFilterFactory - 在指定请求中增加请求头参数的过滤器。
  • ③ StripPrefixGatewayFilterFactory - 在指定请求中处理路径前缀的过滤器。

在Gateway中使用过滤器的方式非常简单,只要在配置文件中通过过滤器命名前缀即可快速使用,如使用AddRequestParameterGatewayFilterFactory,可以通过AddRequestParameter在配置文件中配置使用;如使用StripPrefixGatewayFilterFactory,可以通过StripPrefix在配置文件中配置使用。

具体配置过程如下:

server:
  port: 9000
spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: false  # 开启Gateway自动服务注册和发现的功能
          lower-case-service-id: true  # 将请求路径上的服务名配置为小写
      routes:
        - id: openfeign-client # 唯一命名
          uri: lb://openfeign-client # 转发路径,lb代表loadbalance,即从Eureka中获取的服务列表负载均衡器。 openfeign-client即服务名称,相当于http://localhost:8082/
          predicates: # 定义映射
            - Path=/client/**  # 发送到Gateway网关上的请求路径映射,此映射匹配的路径都会转发到uri上。 具体地址为: lb://openfeign-client/client/**
          filters:
            - StripPrefix=1 # 请求转发时,会自动过滤请求转发的第一节地址,即client。最终地址为: lb://openfeign-client/**
            - AddRequestParameter=id, 0 # 在请求中自动增加一个请求参数,参数名为id,参数值为0。可以用于提供固定参数。
            - AddRequestParameter=name, testFilter # 每个AddRequestParameter过滤器,只能提供一个请求参数,提供多请求参数,需要定义多个过滤器。
            - AddRequestHeader=my-header, test-header-value # 在请求中自动增加一个请求头参数,参数名为my-header,参数值为test-header-value。
        - id: openfeign-service
          uri: lb://openfeign-service
          predicates:
            - Path=/service/**
          filters:
            - StripPrefix=1

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

2 自定义过滤器

2.1 自定义GatewayFilter - 网关过滤器

1) 自定义过滤器

package 

2)配置文件

server:
  port: 9000
spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: false  # 开启Gateway自动服务注册和发现的功能
          lower-case-service-id: true  # 将请求路径上的服务名配置为小写
      routes:
        - id: openfeign-client # 唯一命名
          uri: lb://openfeign-client # 转发路径,lb代表loadbalance,即从Eureka中获取的服务列表负载均衡器。 openfeign-client即服务名称,相当于http://localhost:8082/
          predicates: # 定义映射
            - Path=/client/**  # 发送到Gateway网关上的请求路径映射,此映射匹配的路径都会转发到uri上。 具体地址为: lb://openfeign-client/client/**
          filters:
            - StripPrefix=1 # 请求转发时,会自动过滤请求转发的第一节地址,即client。最终地址为: lb://openfeign-client/**
            - AddRequestParameter=id, 0 # 在请求中自动增加一个请求参数,参数名为id,参数值为0。可以用于提供固定参数。
            - AddRequestParameter=name, testFilter # 每个AddRequestParameter过滤器,只能提供一个请求参数,提供多请求参数,需要定义多个过滤器。
            - AddRequestHeader=my-header, test-header-value # 在请求中自动增加一个请求头参数,参数名为my-header,参数值为test-header-value。
            - Authentication=token
        - id: openfeign-service
          uri: lb://openfeign-service
          predicates:
            - Path=/service/**
          filters:
            - StripPrefix=1

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

2.2 自定义GlobalFilter - 全局过滤器

GlobalFilter:全局过滤器,不需要在配置文件中配置,作用在所有的路由上,最终通过GatewayFilterAdapter包装成GatewayFilterChain可识别的过滤器,它为请求业务以及路由的URI转换为真实业务服务的请求地址的核心过滤器,不需要配置,系统初始化时加载,并作用在每个路由上。

全局过滤器无需创建工厂类,也无需在配置文件中进行注册。因为其对所有的网关代理的路径都生效。

1) 自定义过滤器

package 

六、使用Spring Cloud Gateway实现熔断功能

Spring Cloud Gateway也可以利用Hystrix的熔断特性,在流量过大时进行服务降级。

1. POM依赖

<?xml version="1.0" encoding="UTF-8"?>

2. 熔断处理代码

package 

3. 配置文件

server:
  port: 9000
spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: false  # 开启Gateway自动服务注册和发现的功能
          lower-case-service-id: true  # 将请求路径上的服务名配置为小写
      routes:
        - id: openfeign-client # 唯一命名
          uri: lb://openfeign-client # 转发路径,lb代表loadbalance,即从Eureka中获取的服务列表负载均衡器。 openfeign-client即服务名称,相当于http://localhost:8082/
          predicates: # 定义映射
            - Path=/client/**  # 发送到Gateway网关上的请求路径映射,此映射匹配的路径都会转发到uri上。 具体地址为: lb://openfeign-client/client/**
          filters:
            - StripPrefix=1 # 请求转发时,会自动过滤请求转发的第一节地址,即client。最终地址为: lb://openfeign-client/**
            - AddRequestParameter=id, 0 # 在请求中自动增加一个请求参数,参数名为id,参数值为0。可以用于提供固定参数。
            - AddRequestParameter=name, testFilter # 每个AddRequestParameter过滤器,只能提供一个请求参数,提供多请求参数,需要定义多个过滤器。
            - AddRequestHeader=my-header, test-header-value # 在请求中自动增加一个请求头参数,参数名为my-header,参数值为test-header-value。
            - Authentication=token
            - name: Hystrix # 开启Hystrix容错过滤器
              args:
                name: fallbackcmd # 熔断错误
                fallbackUri: forward:/fallback # 出现服务调用问题,访问的本地路径是什么,也就是本地熔断处理逻辑
        - id: openfeign-service
          uri: lb://openfeign-service
          predicates:
            - Path=/service/**
          filters:
            - StripPrefix=1

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

hystrix:
  command:
    default:
      execution:
        timeout:
          # 如果enabled设置为false,则请求超时交给ribbon控制,为true,则超时作为容错根据
          enabled: true
        isolation:
          thread:
            timeoutInMilliseconds: 1000 # 超时时间,默认1000ms

4. 启动类

package 

需要更多Java学习资料的小伙伴可以到评论区留言或私信我获取哦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值