跳转至

网关#

约 312 个字 35 行代码 2 张图片 预计阅读时间 7 分钟

网关的作用#

  • 反向代理
  • 统一认证鉴权
  • 流量控制
  • 熔断
  • 日志监控

入门案例#

引入相关依赖:

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>3.3.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.luguosong</groupId>
    <artifactId>gateway-hello</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>gateway-hello</name>
    <description>gateway-hello</description>
    <url/>
    <licenses>
        <license/>
    </licenses>
    <developers>
        <developer/>
    </developers>
    <scm>
        <connection/>
        <developerConnection/>
        <tag/>
        <url/>
    </scm>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>2023.0.3</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2023.0.1.2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--服务注册和发现-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</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>
    </dependencies>

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

</project>

配置路由和断言:

application.yml
spring:
  application:
    name: gateway-hello
  cloud:
    nacos:
      server-addr: 127.0.0.1:8848
    gateway:
      routes:
        - id: gateway-server1
          uri: lb://gateway-server1
          predicates:
            - Path=/gateway-server1/**
        - id: gateway-server2
          uri: lb://gateway-server2
          predicates:
            - Path=/gateway-server2/**
      default-filters:
        - StripPrefix=1
server:
  port: 8083

路由#

路由:网关的基本构建块。它由一个ID、一个目标URI、一组断言和一组过滤器定义。如果断言集合为真,则匹配该路由。

url属性#

配置地址#

YAML
spring:
  cloud:
    gateway:
      routes:
        - id: gateway-server1
          uri: https://example.org
          predicates:
            - Path=/**

负载均衡#

需要引入spring-cloud-starter-loadbalancer,负载均衡到nacos服务。

YAML
spring:
  cloud:
    gateway:
      routes:
        - id: gateway-server1
          uri: lb://gateway-server1
          predicates:
            - Path=/**

断言(Predicates)#

这是一个 Java 8 函数断言。输入类型是 Spring Framework 的 ServerWebExchange。这允许您匹配 HTTP 请求中的任何内容,例如头信息或参数。

路由断言

过滤器(Filters)#

这些是使用特定工厂构建的GatewayFilter实例。在这里,您可以在发送下游请求之前或之后修改请求和响应。

网关过滤器

过滤器对所有路由生效#

default-filters配置表示过滤器对所有路由生效

YAML
spring:
  cloud:
    gateway:
      routes:
        - id: gateway-server1
          uri: lb://gateway-server1
          predicates:
            - Path=/**
        - id: gateway-server2
          uri: lb://gateway-server2
          predicates:
            - Path=/**
      default-filters:
        - StripPrefix=1

自定义路由过滤器#

创建路由过滤器工厂:

PrintAnyGatewayFilterFactory.java
package com.upda.gatewaycustomgatewayfilter.filter;

import lombok.Data;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.OrderedGatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;

/**
 * PrintAnyGatewayFilterFactory类名,其中
 * 前半段PrintAny:对应配置文件中过滤器的键值
 * 后半段GatewayFilterFactory:是固定写法,方便配置使用
 *
 * @author luguosong
 */
@Component
public class PrintAnyGatewayFilterFactory extends AbstractGatewayFilterFactory<PrintAnyGatewayFilterFactory.Config> {

    @Override
    public GatewayFilter apply(Config config) {
        /*
        * 参数一:路由过滤器
        * 参数二:过滤器执行顺序
        * */
        return new OrderedGatewayFilter(
                new GatewayFilter() {
                    @Override
                    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

                        System.out.println("自定义路由过滤器执行");
                        System.out.println("参数一:" + config.getA());
                        System.out.println("参数二:" + config.getB());
                        System.out.println("参数三:" + config.getC());

                        return chain.filter(exchange);
                    }
                }
                , 0);
    }


    @Data
    public static class Config {
        private String a;
        private String b;
        private String c;
    }

    // 返回Config类中的字段名称,参数将按此顺序获取
    @Override
    public List<String> shortcutFieldOrder() {
        return List.of("a", "b", "c");
    }

    public PrintAnyGatewayFilterFactory() {
        super(Config.class);
    }
}

在配置文件中对指定路由配置过滤器:

application.yml
spring:
  application:
    name: gateway-custom-gateway-filter
  cloud:
    nacos:
      server-addr: 127.0.0.1:8848
    gateway:
      routes:
        - id: gateway-server1
          uri: lb://gateway-server1
          predicates:
            - Path=/gateway-server1/**
          filters:
            - PrintAny=111,222,hello
        - id: gateway-server2
          uri: lb://gateway-server2
          predicates:
            - Path=/gateway-server2/**
      default-filters:
        - StripPrefix=1
server:
  port: 8084

自定义全局过滤器#

定义全局过滤器:

MyGlobalFilter.java
package com.upda.gatewaycustomglobalfilter.filter;

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * @author luguosong
 */
@Component
public class MyGlobalFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 获取request可以进行参数判断
        ServerHttpRequest request = exchange.getRequest();

        System.out.println("全局过滤器执行了");

        return chain.filter(exchange);
    }


    @Override
    public int getOrder() {
        //过滤器执行顺序,值越小越优先
        return 0;
    }
}

不需要在配置文件中进行配置,全局过滤器会直接生效。

评论