springcloud gateway网关

gateway网关功能:服务路由、负载均衡、请求限流、跨域问题统一解决配置、身份认证和权限校验等

下面记录一下gateway网关的基本功能和配置。PS:没有使用注册中心

目录

1、添加依赖

2、配置文件

3、限流配置

4、过滤器配置

4.1全局过滤器

4.2 局部过滤器

5、跨域问题统一解决配置




1、添加依赖

主要依赖

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

        <!-- gateway基于Redis实现限流 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
        </dependency>

完整依赖

<?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">

    <!-- 声明依赖 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.13</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.zhh</groupId>
    <artifactId>gateway</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>gateway</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.6.13</spring-boot.version>
    </properties>

    <dependencies>

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

        <!-- gateway基于Redis实现限流,如果不需要限流功能,就不需要该依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

    </dependencies>

    <dependencyManagement>
        <dependencies>

    <!-- SpringBoot相关依赖管理,上面parent标签已经声明了 spring-boot-starter-parent,这里注释掉-->
<!--            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>-->

            <!-- SpringCloud 相关依赖管理 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>2021.0.6</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>

    </dependencyManagement>

    <build>
        <plugins>
            <!-- 编译插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <!-- 打包插件 -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <configuration>
                    <!-- 启动类,主类全路径 -->
                    <mainClass>com.zhh.gateway.GatewayApplication</mainClass>
                    <skip>true</skip>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

2、配置文件
 

完整的配置文件,包含了路由(自带负载均衡)、过滤器、限流

server:
  port: 8088

spring:
  application:
    name: cloud-gateway # 本服务名称
  cloud:
    gateway:

      # 解决跨域问题的配置
      globalcors:
        add-to-simple-url-handler-mapping: true
        cors-configurations:
          '[/**]':  #拦截的请求
            allowedOrigins: "*"#允许跨域的请求
            allowedMethods: "*" #运行跨域的请求方式
            allowedHeaders: "*" #允许请求中携带的头信息
            allowedCredentials: true #是否允许携带cookie
            maxAge: 36000 #跨域检测的有效期,单位s,在这个时间段里,对于相同的跨域请求不会再预检

      # 路由,如果有注册中心,那就自带负载均衡功能
      routes:
        - id: svs1  #路由的ID,没有固定规则但要求唯一,建议使用服务名称
          uri: http://127.0.0.1:8080 #匹配后提供服务的路由地址
          predicates:
            - Path=/svs1/**         # 断言,路径相匹配的进行路由
          filters:
            - StripPrefix=1 #移除第x个前缀,127.0.0.1:8088/svs1/api/find > 127.0.0.1:8088/api/find
            #- PrefixPath=/demo #添加前缀  127.0.0.1:8088/api/find > 127.0.0.1:8088/demo/api/find

            # 局部过滤器
            - name: Order # 自定义的局部过滤器,前缀匹配,过滤器必须是GatewayFilterFactory结尾
              args:
                param1: 6688 # 过滤器中的参数

            # gateway默认的限流过滤器
            - name: RequestRateLimiter	#过滤器名称
              args:
                key-resolver: "#{@urlKeyResolver}" #使用SpEL表达式根据#{@beanName}从 Spring 容器中获取 Bean 对象
                redis-rate-limiter.replenishRate: 1 # 令牌桶填充的速率,每秒多少个令牌
                redis-rate-limiter.burstCapacity: 1 # 令牌桶总容量


          # 第二个路由
        - id: svs2
          uri: http://127.0.0.1:8001
          predicates:
            - Path=/svs2/**

  # Redis参数配置,这里简单配置一下,其他参数使用默认的即可
  # 如果不需要限流功能,就不需要相关依赖和配置
  redis:
    database: 0
    host: 127.0.0.1
    port: 6379
    password:

3、限流配置

package com.zhh.gateway.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import reactor.core.publisher.Mono;

/**
 * 限流配置
 */
@Slf4j
@Configuration
public class KeyResolverConfig {

    // KeyResolver的Bean只能配置一个,其他的注释掉
    
    /**
     * 基于url限流
     */
    @Bean
    public KeyResolver urlKeyResolver() {
        log.info("限流Bean初始化,BeanName=urlKeyResolver");
        return exchange -> {
            String url = exchange.getRequest().getPath().toString();
            log.info("基于url限流,url:{}",url);
            return Mono.just(url);
        };
    }

    /**
     * 基于ip限流
     */
/*    @Bean
    public KeyResolver ipKeyResolver() {
        log.info("限流Bean初始化,BeanName=ipKeyResolver");
        return exchange -> {
            String ip = exchange.getRequest().getRemoteAddress().getAddress().getHostAddress();
            log.info("基于ip限流,ip:{}",ip);
            return Mono.just(ip);
        };
    }*/

}

对应配置文件中的配置

            # gateway默认的限流过滤器
            - name: RequestRateLimiter	#过滤器名称
              args:
                key-resolver: "#{@urlKeyResolver}" #使用SpEL表达式根据#{@beanName}从 Spring 容器中获取 Bean 对象
                redis-rate-limiter.replenishRate: 1 # 令牌桶填充的速率,每秒多少个令牌
                redis-rate-limiter.burstCapacity: 1 # 令牌桶总容量

对应pom文件中的Redis依赖

        <!-- gateway基于Redis实现限流 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
        </dependency>

gateway默认使用的是令牌桶算法配合Redis实现的限流,如果不使用限流功能,可以不需要引入修改依赖和配置。

注:3.x版本的Redis可能会出现限流无效,最好使用4.x及以上版本。

4、过滤器配置

4.1全局过滤器

全局过滤器写好代码后全局生效,不需要在配置文件中配置。

下例:编写一个全局过滤器,对所有的请求都输出日志

package com.zhh.gateway.filter;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * 全局过滤器
 */
@Slf4j
@Component
public class LoggingFilter implements GlobalFilter, Ordered {

    /**
     * 全局过滤器,打印所有请求的日志
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String uri = exchange.getRequest().getPath().value();
        log.info("全局过滤器, URI:{}", uri);
        return chain.filter(exchange);
    }

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

4.2 局部过滤器

局部过滤器只针对特定路由生效,编码后需要在配置文件中配置,哪个路由需要就在哪个路由上加上对应的过滤器名称。
 

局部过滤器类名称必须是GatewayFilterFactory结尾,例:xxxGatewayFilterFactory

下例:编写一个局部过滤器,在对应的请求头中添加参数

package com.zhh.gateway.filter;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;

/**
 * 局部过滤器
 * 哪个路由需要该过滤器就在哪个路由的配置上添加该路由标识
 * 局部过滤器类名称必须是GatewayFilterFactory结尾,例:xxxGatewayFilterFactory
 */
@Slf4j
@Component
public class OrderGatewayFilterFactory extends AbstractGatewayFilterFactory<OrderGatewayFilterFactory.Config> {

    public OrderGatewayFilterFactory() {
        super(Config.class);
        log.info("初始化局部过滤器");
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            ServerHttpRequest request = exchange
                    .getRequest()
                    .mutate()
                    // 在请求头中添加参数和值
                    .header("flag", config.getParam1())
                    .build();
            log.info("在请求头中添加参数和值:[{}]", config.getParam1());
            return chain.filter(exchange.mutate().request(request).build());
        };
    }

    /**
     * 读取配置文件中的参数,可配置多个属性
     */
    @Data
    public static class Config {
        private String param1;
        private String param2;
    }
}

对应配置文件中的配置

          filters:
            # 局部过滤器
            - name: Order # 自定义的局部过滤器,前缀匹配,局部过滤器类名称必须是GatewayFilterFactory结尾,例:xxxGatewayFilterFactory
              args:
                param1: 6688 # 过滤器中的参数

5、跨域问题统一解决配置

目前很多应用都是前后端分离的架构,但这样相比之前的单应用系统就会带来跨域的问题,如果有多个很多服务,就可以在gateway网关层做统一的跨域解决

在配置文件中添加跨域配置即可
 

spring:
  application:
    name: cloud-gateway # 本服务名称
  cloud:
    gateway:
      # 解决跨域问题的配置
      globalcors:
        add-to-simple-url-handler-mapping: true
        cors-configurations:
          '[/**]':  #拦截的请求
            allowedOrigins: "*"#允许跨域的请求
            allowedMethods: "*" #运行跨域的请求方式
            allowedHeaders: "*" #允许请求中携带的头信息
            allowedCredentials: true #是否允许携带cookie
            maxAge: 36000 #跨域检测的有效期,单位s,在这个时间段里,对于相同的跨域请求不会再预检

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值