目录

  • 1.简介
  • Gateway 核心概念
  • Gateway 工作模型
  • 2.实例
  • 2.1 快速入门-断言工厂
  • 2.1.1 After 路由断言工厂
  • 2.1.2 Header断言工厂
  • 2.1.3 Cookie路由断言工厂
  • 2.1.4 Host路由断言工厂
  • 2.1.5 Method路由断言工厂
  • 2.1.6 Path路由断言工厂
  • 2.1.7 Query路由断言工厂
  • 2.2 过滤器


1.简介

Spring Cloud Gateway是Spring Cloud官方推出的第二代网关框架,取代Zuul网关。网关作为流量的,在微服务系统中有着非常作用,网关常见的功能有路由转发、权限校验、限流控制等作用。

Spring Cloud Gateway是Spring官方最新推出的一款基于Spring Framework 5,Project Reactor和Spring Boot 2之上开发的网关。与zuul1.0不同的是,gateway是异步非阻塞的(netty+webflux实现),zuul1.0是同步阻塞请求的。gateway的数据是封装在ServerWebExchange中,zuul是存放在RequestContext里的(这里是重点,圈起来!)Gateway相对于Zuul来说,在路由的配置上更加多样化,配置更加简便。

官方文档 : https://docs.spring.io/spring-cloud-gateway/docs/2.2.5.RELEASE/reference/html/#gateway-starter

Gateway 核心概念

  • Route 路由,它是网关的基础元素,包含ID、目标URI、断言、过滤器组成,当前请求到达网关时,会通过Gateway Handler
    Mapping,基于断言进行路由匹配,当断言为true时,匹配到路由进行转发
  • Predicate,断言,学过java8的同学应该知道这个函数,它可以允许开发人员去匹配HTTP请求中的元素,一旦匹配为true,则表示匹配到合适的路由进行转发
  • Filter,过滤器,可以在请求发出的前后进行一些业务上的处理,比如授权、埋点、限流等。

Gateway 工作模型

SpringCloudGateway使用Skywalking后获取traceId springcloud的gateway_请求头


其中,predicate就是我们的匹配条件;而filter,就可以理解为一个无所不能的拦截器。有了这两个元素,再加上目标uri,就可以实现一个具体的路由了。客户端向 Spring Cloud Gateway 发出请求,如果请求与网关程序定义的路由匹配,则该请求就会被发送到网关 Web 处理程序,此时处理程序运行特定的请求过滤器链。过滤器之间用虚线分开的原因是过滤器可能会在发送代理请求的前后执行逻辑。所有 pre 过滤器逻辑先执行,然后执行代理请求;代理请求完成后,执行 post 过滤器逻辑。

2.实例

2.1 快速入门-断言工厂

2.1.1 After 路由断言工厂

新建一个springboot的项目eureka-gateway-client
pom如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>eureka-gateway-client</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>eureka-gateway-client</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>com.example</groupId>
        <artifactId>demo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <relativePath/>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

新增工程配置文件application.yml

server:
  port: 8767

spring:
  profiles:
    active: after_route
---
spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: http://httpbin.org:80
        predicates:
        - After=2020-10-07T11:14:47.789-07:00[America/Denver]
  profiles: after_route

启动类

@SpringBootApplication
public class eurekaGatewayApplication {

    public static void main(String[] args) {
        SpringApplication.run(eurekaGatewayApplication.class, args);
    }
}

注意看,此时我们定了一个事件,在2020-10-07T11:14:47.789-07:00[America/Denver]之后的的我们输入http://localhost:8767/get会被转发成http://httpbin.org:80/get
如果配置改动的时间在此之后即当前时间之后,会报404。

2.1.2 Header断言工厂

Header路由断言工厂需要两个参数,分别是Header键和Header的值,Header值可以是一个正则表达式,当请求头匹配了断言的Header的键和值,断言通过,进入路由的逻辑否则,返回错误信息
修改application.yml

server:
  port: 8767

spring:
  profiles:
    active: header_route
---
spring:
  cloud:
    gateway:
      routes:
      - id: header_route
        uri: http://httpbin.org:80
        predicates:
        - Header=X-Request-Id, \d+
  profiles: header_route

配置好了断言工厂,启动工程
采取curl命令

curl -H 'X-Request-Id:1' localhost:8767/get

或者postman

SpringCloudGateway使用Skywalking后获取traceId springcloud的gateway_spring_02

2.1.3 Cookie路由断言工厂

Cookie路由断言工厂需要两个参数吗,分别是Cookie名和Cookie的值,Cookie的值可以为正则表达式,当请求头带有Cookie,并且请求的Cookie和断言配置的Cookie相匹配,请求能够被正确路由,否则报404错误
修改配置

server:
  port: 8767

spring:
  profiles:
    active: cookie_route
---
spring:
  cloud:
    gateway:
      routes:
      - id: cookie_route
        uri: http://httpbin.org:80
        predicates:
        - Cookie=name, forezp
  profiles: cookie_route

然后使用curl命令

curl -H ‘Cookie:name=forezp’ localhost:8767/get

或者postman

SpringCloudGateway使用Skywalking后获取traceId springcloud的gateway_maven_03

2.1.4 Host路由断言工厂

Host路由断言工厂需要一个参数==HostName,它可以采取.* 等去匹配Host。这个参数会匹配请求头中的Host的值,如果匹配成功,则请求正确转发

server:
  port: 8767

spring:
  profiles:
    active: host_route
---
spring:
  cloud:
    gateway:
      routes:
      - id: host_route
        uri: http://httpbin.org:80
        predicates:
        - Host=**.lulinfeng.com
  profiles: host_route

在上面的配置中,请求头中含有Host后缀为lulinfeng.com

curl -H ‘Host:www.lulinfeng.com’ localhost:8767/get

2.1.5 Method路由断言工厂

这个可以过滤请求类型,只限制了GET类型可以进入

server:
  port: 8767

spring:
  profiles:
    active: method_route
---
spring:
  cloud:
    gateway:
      routes:
      - id: method_route
        uri: http://httpbin.org:80
        predicates:
        - Method=GET
  profiles: method_route

如果用post的话就会报404

curl -XPOST localhost:8767/get

2.1.6 Path路由断言工厂

Path路演断言工厂即路径路由断言工厂,当请求路径和配置的请求路径相匹配时,则路由通过。该断言工厂需要配置一个参数-应用匹配路径,可以是一个spel表达式。

server:
  port: 8767

spring:
  profiles:
    active: path_route
---
spring:
  cloud:
    gateway:
      routes:
      - id: path_route
        uri: http://httpbin.org:80
        predicates:
        - Path=/forezp/article/details/{segment}
  profiles: path_route

在上面配置中所有满足/forezp/article/details/{segment}路径的请求都会和匹配的路径相匹配,并且被路由,比如路径为forezp/article/details/12345678的请求,将会被命中匹配,并成功转发。

curl localhost:8767/forezp/article/details/12345678

2.1.7 Query路由断言工厂

server:
  port: 8767

spring:
  profiles:
    active: query_route
---
spring:
  cloud:
    gateway:
      routes:
      - id: query_route
        uri: http://httpbin/org
        predicates:
        - Query=foo, ba.
  profiles: query_route

访问 http://localhost:8767/get?foo=bar

2.2 过滤器

由过滤器工作流点可以知道过滤器有着非常重要的作用,在pre类型的过滤器可以实现参数校验,权限校验,流量监控,日志输出,协议转换等功能,在post类型的过滤器中可以做响应内容,响应头的修改,日志输出,流量监控等功能。要弄清楚为什么需要网关这一层,就不得不提过滤器的作用了。
当我们有很多服务的时候以下图为例子

需要获取到更详细的信息可以惨开官网 :https://docs.spring.io/spring-cloud-gateway/docs/2.2.5.RELEASE/reference/html/#gatewayfilter-factories