Spring Cloud GateWay基本使用,一看就会,确定不看看?

Spring Cloud GateWay基本使用

Spring Cloud GateWay

概念

什么是网关

Spring Cloud GateWay基本使用,一看就会,确定不看看?

网关是一个服务,是访问内部系统的唯一入口,提供内部服务的路由中转,额外还可以在此基础上提供如身份验证、监控、负载均衡、限流、降级与应用检测等功能。

配置

  1. pom.xml
<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>gateway</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>gateway</name>
    <description>gateway</description>
    <properties>
        <java.version>17</java.version>
        <repackage.classifier/>
        <spring-cloud.version>2021.0.1</spring-cloud.version>
        <spring-native.version>0.11.2</spring-native.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.experimental</groupId>
            <artifactId>spring-native</artifactId>
            <version>${spring-native.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.projectreactor</groupId>
            <artifactId>reactor-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
            <version>2.1.3.RELEASE</version>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.retry</groupId>
            <artifactId>spring-retry</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-circuitbreaker-reactor-resilience4j</artifactId>
            <version>2.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                    <classifier>${repackage.classifier}</classifier>
                    <image>
                        <builder>paketobuildpacks/builder:tiny</builder>
                        <env>
                            <BP_NATIVE_IMAGE>true</BP_NATIVE_IMAGE>
                        </env>
                    </image>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.experimental</groupId>
                <artifactId>spring-aot-maven-plugin</artifactId>
                <version>${spring-native.version}</version>
                <executions>
                    <execution>
                        <id>test-generate</id>
                        <goals>
                            <goal>test-generate</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>generate</id>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    <repositories>
        <repository>
            <id>spring-releases</id>
            <name>Spring Releases</name>
            <url>https://repo.spring.io/release</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>spring-releases</id>
            <name>Spring Releases</name>
            <url>https://repo.spring.io/release</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>

    <profiles>
        <profile>
            <id>native</id>
            <properties>
                <repackage.classifier>exec</repackage.classifier>
                <native-buildtools.version>0.9.9</native-buildtools.version>
            </properties>
            <dependencies>
                <dependency>
                    <groupId>org.junit.platform</groupId>
                    <artifactId>junit-platform-launcher</artifactId>
                    <scope>test</scope>
                </dependency>
            </dependencies>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.graalvm.buildtools</groupId>
                        <artifactId>native-maven-plugin</artifactId>
                        <version>${native-buildtools.version}</version>
                        <extensions>true</extensions>
                        <executions>
                            <execution>
                                <id>test-native</id>
                                <phase>test</phase>
                                <goals>
                                    <goal>test</goal>
                                </goals>
                            </execution>
                            <execution>
                                <id>build-native</id>
                                <phase>package</phase>
                                <goals>
                                    <goal>build</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>

</project>

  1. DemoApplication
@SpringBootApplication
public class GatewayApplication {

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

}

服务准备

Provider

  1. pom.xml
<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>provider</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>provider</name>
    <description>provider</description>
    <properties>
        <java.version>17</java.version>
        <repackage.classifier/>
        <spring-native.version>0.11.2</spring-native.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.experimental</groupId>
            <artifactId>spring-native</artifactId>
            <version>${spring-native.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                    <classifier>${repackage.classifier}</classifier>
                    <image>
                        <builder>paketobuildpacks/builder:tiny</builder>
                        <env>
                            <BP_NATIVE_IMAGE>true</BP_NATIVE_IMAGE>
                        </env>
                    </image>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.experimental</groupId>
                <artifactId>spring-aot-maven-plugin</artifactId>
                <version>${spring-native.version}</version>
                <executions>
                    <execution>
                        <id>test-generate</id>
                        <goals>
                            <goal>test-generate</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>generate</id>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    <repositories>
        <repository>
            <id>spring-releases</id>
            <name>Spring Releases</name>
            <url>https://repo.spring.io/release</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>spring-releases</id>
            <name>Spring Releases</name>
            <url>https://repo.spring.io/release</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>

    <profiles>
        <profile>
            <id>native</id>
            <properties>
                <repackage.classifier>exec</repackage.classifier>
                <native-buildtools.version>0.9.9</native-buildtools.version>
            </properties>
            <dependencies>
                <dependency>
                    <groupId>org.junit.platform</groupId>
                    <artifactId>junit-platform-launcher</artifactId>
                    <scope>test</scope>
                </dependency>
            </dependencies>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.graalvm.buildtools</groupId>
                        <artifactId>native-maven-plugin</artifactId>
                        <version>${native-buildtools.version}</version>
                        <extensions>true</extensions>
                        <executions>
                            <execution>
                                <id>test-native</id>
                                <phase>test</phase>
                                <goals>
                                    <goal>test</goal>
                                </goals>
                            </execution>
                            <execution>
                                <id>build-native</id>
                                <phase>package</phase>
                                <goals>
                                    <goal>build</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>

</project>

  1. ProviderApplication
@SpringBootApplication
public class ProviderApplication {

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

}

  1. application.yml
server:
  port: 8090
  1. DemoController
@RestController
public class DemoController {

    @GetMapping("/hello")
    public String hello(HttpServletRequest request){
        return "provider hello";
    }


    @GetMapping("/before")
    public String before(){
        return "before";
    }

    @GetMapping("/after")
    public String after(){
        return "after";
    }
}

基本操作

基本使用,直接透传

spring:
  cloud:
    gateway:
      routes:
      - id: hello
        uri: http://localhost:8090 # 将所有请求转发到另一台机器上

路径匹配

访问localhost:8080/hello时会被转发到http://localhost:8090/hello/**

spring:
  cloud:
    gateway:
      routes:
      - id: hello
        uri: http://localhost:8090
        predicates:
        - Path=/hello/**

请求方法匹配

当通过put的形式访问localhost:8080/hello时,会被转发到http://localhost:8090/hell

spring:
  main:
    web-application-type: reactive
    allow-bean-definition-overriding: true
  cloud:
    gateway:
      routes:
        - id: cookie_route
          uri: http://localhost:8090
          predicates:
          - Method=Put

参数匹配

当请求localhost:8080?hello时会匹配,并进行处理

spring:
  main:
    web-application-type: reactive
    allow-bean-definition-overriding: true
  cloud:
    gateway:
      routes:

        - id: cookie_route
          uri: http://localhost:8090
          predicates:
          - Query=hello, 1

        - id: cookie_route
          uri: http://localhost:8090
          predicates:
          - Query=hello

请求的时间匹配

只有在符合时间点时请求才会被转发,可以用于限时业务场景

spring:
  cloud:
    gateway:
      routes:
       - id: before
         uri: http://localhost:8090
         predicates:
           - Before=2022-02-19T15:23:43.251650+08:00[Asia/Shanghai]
       - id: after
          uri: http://localhost:8090
          predicates:
            - After=2022-02-19T15:30:43.251650+08:00[Asia/Shanghai]
       - id: after
         uri: http://localhost:8090
         predicates:
           - Between=2022-02-19T15:29:43.251650+08:00[Asia/Shanghai],2022-02-19T15:30:43.251650+08:00[Asia/Shanghai]

Cookie匹配

spring:
  main:
    web-application-type: reactive
    allow-bean-definition-overriding: true
  cloud:
    gateway:
      routes:
        - id: cookie_route
          uri: http://localhost:8090
          predicates:
            - Cookie=name, qzj


Header匹配

spring:
  main:
    web-application-type: reactive
    allow-bean-definition-overriding: true
  cloud:
    gateway:
      routes:
        - id: cookie_route
          uri: http://localhost:8090
          predicates:
            - Header=name, qzj

域名匹配

spring:
  main:
    web-application-type: reactive
    allow-bean-definition-overriding: true
  cloud:
    gateway:
      routes:
        - id: cookie_route
          uri: http://localhost:8090
          predicates:
          - Host=**.qzj.com

转发路径处理

spring:
  main:
    web-application-type: reactive
    allow-bean-definition-overriding: true
  cloud:
    gateway:
      routes:
        - id: cookie_route
          uri: http://localhost:8090
          predicates:
            - Header=name, qzj
          # 先predicates 再 filters
          # 如果没有显示设置predicates则每个请求头都会添加
          filters:
            - AddRequestHeader=gender, Male

        - id: cookie_route
          uri: http://localhost:8090
          predicates:
            - Path=/hello/**
          filters:
            - AddResponseHeader=gender, Male

        - id: add_response_header_route
          uri: http://localhost:8090
          predicates:
            - Path=/{segment}/hello/**
          filters:
            - AddResponseHeader=foo, bar-{segment}
            - StripPrefix=1

        - id: prefixpath_route
          uri: http://localhost:8090
          predicates:
            - Path=/**
          filters:
            - PrefixPath=/demo2

限流

  1. 使用令牌桶算法进行限流
  2. 需要自定义KeyResolve来作为限流限制的对象,否则会报403 Forbidden错误!!!
  3. 需要添加pom依赖 org.springframework.boot:spring-boot-starter-data-redis-reactive
spring:
  main:
    web-application-type: reactive
    allow-bean-definition-overriding: true
  cloud:
    gateway:
      routes:
        - id: requestratelimiter_route
          uri: http://localhost:8090
          predicates:
            - Path=/**
          filters:
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 2 # 当使用完令牌后,往桶里添加令牌的速率
                redis-rate-limiter.burstCapacity: 2 # 桶里初始令牌数
                redis-rate-limiter.requestedTokens: 1 # 每个请求消耗令牌数
                key-resolver: "#{@myIpKeyResolver}" # 限制的对象

KeyResolver实现

		@Bean
    KeyResolver myIpKeyResolver() {
        return exchange -> Mono.just(Objects.requireNonNull(exchange.getRequest().getLocalAddress()).toString());
    }

重定向

spring:
  main:
    web-application-type: reactive
    allow-bean-definition-overriding: true
  cloud:
    gateway:
      routes:
        - id: prefixpath_route
          uri: http://localhost:8090
          predicates:
            - Path=/hello/*
          filters:
            - RedirectTo=302, http://localhost:8070

转发

spring:
  main:
    web-application-type: reactive
    allow-bean-definition-overriding: true
  cloud:
    gateway:
      routes:
        - id: rewritepath_route
          uri: http://localhost:8090
          predicates:
            - Path=/hello/**
          filters:
            - SetPath=/before

负载均衡

对于一个集群,当访问localhost:8080/hello时,会有80%的请求转发到http://localhost:807机器处理,20%转发到http://localhost:8090被处理

spring:
  main:
    web-application-type: reactive
    allow-bean-definition-overriding: true
  cloud:
    gateway:
      routes:
        - id: consumer
          uri: http://localhost:8070
          predicates:
            - Weight=group1, 8
        - id: provider
          uri: http://localhost:8090
          predicates:
            - Weight=group1, 2

上一篇:ROS2养成计划(一)发展历程和开发环境安装


下一篇:狂神说笔记——SpringBoot操作数据库22-2