Spring-Cloud 微服务网关GateWay的过滤和限流

本文详细介绍了如何在Spring Cloud Gateway中实现微服务网关的功能,包括创建Gateway模块、配置动态路由、自定义过滤器以校验请求头以及设置基于Redis的限流策略。通过实例演示了如何通过Gateway访问微服务,并展示了如何监控限流效果。
摘要由CSDN通过智能技术生成

一. 案例

1. 创建 gateway 模块

在这里插入图片描述

2. 导入依赖

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

gateway和web依赖存在冲突,所以需要将父模块中的 spring-boot-startet-web 依赖分别添加到需要使用的子模块中,不然启动会出现如下错误
在这里插入图片描述

3. 创建 application.yml 文件

server:
  port: 7005
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka/
  instance:
    prefer-ip-address: true
spring:
  application:
    name: gateway-server
  cloud:
    gateway:
      routes:
        - id: integral-server # 自定义路由id,唯一
          uri: http://127.0.0.1:8001
          predicates: #路由条件,Predicate 接受一个输入参数,返回一个布尔值结果
            - Path=/**

4. 创建启动类

package com.ddz;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

5. 在页面就可以通过 gateway 网关访问了

链接:http://localhost:7005/findOrderByUser?uid=1

二. 动态路由和添加访问路径

在这里插入图片描述

1. 添加依赖

        <!-- eureka -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

2. 修改 application.yml 中配置

    gateway:
      routes:
        - id: user-server # 自定义路由id,唯一
          uri: lb://user-server
          predicates: #路由条件,Predicate 接受一个输入参数,返回一个布尔值结果
            - Path=/user/**  # 访问url
          filters: # 访问真实路径 
          -RewritePath=/user/(?<segment>/?.*), $\{segment}

真实路径替换 /user/(?/?.*), ${segment} 例如: localhost:8080/user/get 转换后 localhost:8080/get
不明白的可以参考博客

在这里插入图片描述

3. 在页面访问路径

链接:http://localhost:7005/user/findOrderByUser?uid=1

三. GateWay 过滤器

1. 在 filters 包下 创建 PowerFilter类

校验所有请求的请求头中是否包含“token”
在这里插入图片描述

2. 在页面访问

再去访问:http://localhost:7005/user/findOrderByUser?uid=1 就会被拦截
在这里插入图片描述

四. GateWay 限流

基于Filter的限流
SpringCloudGateway官方就提供了基于令牌桶的限流支持。基于其内置的过滤器工厂 
RequestRateLimiterGatewayFilterFactory 实现。在过滤器工厂中是通过Redis和lua脚本结合的方式进行流量控制。

1.添加依赖

        <!--监控依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--redis的依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
        </dependency>

2. 在 config 包下创建 LimitConfig 类

package com.ddz.config;

import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Configuration
public class LimitConfig {
    /**
     * 按照 Path 访问次数限流
     *
     * @return key
     */
    @Bean
    public KeyResolver pathKeyResolver() {
        return exchange -> Mono.just(
                exchange.getRequest()
                        .getPath()
                        .toString()
        );
    }
    
//    /**
//     * 按照 Path 访问次数限流
//     */
//    @Bean
//    public KeyResolver pathKeyResolver() {
//        /* 内部类 */
//        return new KeyResolver() {
//            @Override
//            public Mono<String> resolve(ServerWebExchange exchange) {
//                System.out.println("---" + exchange.getRequest().getPath().toString());
//                return Mono.just(exchange.getRequest().getPath().toString());
//            }
//        };
//    }

//   /**
//     * 根据IP限流
//     */
//    @Bean
//    public KeyResolver ipKeyResolver() {
//        return exchange -> Mono.just(
//                exchange.getRequest()
//                        .getRemoteAddress()
//                        .getHostName()
//        );
//    }

    /**
     * 根据token限流
     */
//    @Bean
//    public KeyResolver tokenKeyResolver() {
//        return new KeyResolver() {
//            @Override
//            public Mono<String> resolve(ServerWebExchange exchange) {
//                return Mono.just(exchange.getRequest().getQueryParams().getFirst("token"));
//            }
//        };
//    }

}

3. 修改 application.yml 文件

在这里插入图片描述

          filters:
          - name: RequestRateLimiter #固定的
            args:
              key-resolver: '#{@pathKeyResolver}' # 用于限流的键的解析器的 Bean 对象的名字。它使用 SpEL 表达式根据#{@beanName}从 Spring 容器中获取 Bean 对象。
              redis-rate-limiter.replenishRate: 1 # 令牌桶每秒填充平均速率
              redis-rate-limiter.burstCapacity: 3 # 令牌桶的总容量
  redis:
   host: 127.0.0.1
   port: 6379
   password: ddz123
   database: 3

4. 启动 Redis 服务,并进入客户端输入指令开启监控

在这里插入图片描述

5. 在页面快速连续的访问

链接:http://localhost:7005/user/findOrderByUser?uid=1&token=1001
在这里插入图片描述

6. 查看监控信息

在这里插入图片描述

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LOVE_DDZ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值