• SpringCloud——Gateway(使用redis做限流、跨域)


    限流

    介绍

    限流就是限制一段时间内,用户访问资源的次数,减轻服务器压力,限流大致分为 两种: 1. IP 限流(5s 内同一个 ip 访问超过 3 次,则限制不让访问,过一段时间才可继续访问)
    2. 请求量限流(只要在一段时间内(窗口期),请求次数达到阀值,就直接拒绝后面来的访问了, 过一段时间才可以继续访问)(粒度可以细化到一个 api(url),一个服务)

    限流模型

    漏斗算法 ,令牌桶算法,窗口滑动算法 计数器算法,本次使用令牌桶算法
    在这里插入图片描述

    Gateway结合redis实现请求量限流

    pringCloudGateway已经内置了一个RequestRateLimiterGatewayFilterFactory,我们可以直接使用。注意不是全局过滤,是针对某一个gateway。
    目前RequestRateLimiterGatewayFilterFactory的实现依赖于Redis,所以我们还要引入spring-boot-starter-data-redis-reactive。

    1.添加依赖(在之前gateway项目基础上)

    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-data-redis-reactiveartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4

    2.写配置类

    package com.dcits.gatewayserver.config;
    
    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;
    
    /**
     * 自定义请求限制
     */
    @Configuration
    public class RequestLimitConfig {
        //针对某一个接口ip /doLogin 每一个ip 10s只能访问3次
        @Bean
        public KeyResolver ipKeyResolver(){
            return exchange -> Mono.just(exchange.getRequest().getHeaders().getHost().getHostName());
        }
        //针对路径限制 /doLogin
        //api就是接口 一般将gateway叫api网关
        @Bean
        public KeyResolver apiKeyResolver(){
            return exchange -> Mono.just(exchange.getRequest().getPath().value());
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    3.修改yml文件

    spring:
      application:
        name: gateway-server
      cloud:
        gateway:
          enabled: true # 只要加了依赖默认开启
          routes:
            - id: login-service-route # 路由id,保持唯一
              uri: http://localhost:8081 # uri同一资源定位符
              predicates:
                - Path=/doLogin # 匹配规则,只要路径匹配上/doLogin,就往uri转发,并且将路径带上
              filters:
                - name: RequestRateLimiter # 过滤器名称
                  args: # 过滤器参数
                    key-resolver: '#{@ipKeyResolver}' # 通过spel表达式取IOC容器中Bean的值
                    redis-rate-limiter.replenishRate: 1 # 生成令牌的速度
                    redis-rate-limiter.burstCapacity: 3 # 桶容量
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    4.启动测试

    此时启动会报错找到两个Bean
    在这里插入图片描述解决:
    在配置类中加@Primary注解

    @Configuration
    public class RequestLimitConfig {
        //针对某一个接口ip /doLogin 每一个ip 10s只能访问3次
        @Bean
        @Primary
        public KeyResolver ipKeyResolver(){
            return exchange -> Mono.just(exchange.getRequest().getHeaders().getHost().getHostName());
        }
        //针对路径限制 /doLogin
        //api就是接口 一般将gateway叫api网关
        @Bean
        public KeyResolver apiKeyResolver(){
            return exchange -> Mono.just(exchange.getRequest().getPath().value());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    可以在postman中测试,但是较慢,也可以在浏览器中狂按F5
    正常:
    在这里插入图片描述
    狂按F5被限流:

    在这里插入图片描述
    可以看到是按照ip进行限制
    在这里插入图片描述

    换成API限流进行测试

    修改ym文件:

    spring:
      application:
        name: gateway-server
      cloud:
        gateway:
          enabled: true # 只要加了依赖默认开启
          routes:
            - id: login-service-route # 路由id,保持唯一
              uri: http://localhost:8081 # uri同一资源定位符
              predicates:
                - Path=/doLogin # 匹配规则,只要路径匹配上/doLogin,就往uri转发,并且将路径带上
              filters:
                - name: RequestRateLimiter # 过滤器名称
                  args: # 过滤器参数
                    key-resolver: '#{@apiKeyResolver}' # 通过spel表达式取IOC容器中Bean的值
                    redis-rate-limiter.replenishRate: 1 # 生成令牌的速度
                    redis-rate-limiter.burstCapacity: 3 # 桶容量
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    可以看到按照路径限制
    在这里插入图片描述

    Gateway跨域

    可以克服Ajax只能同源访问

    1.在代码中添加@CrossOrigin

    在这里插入图片描述

    2.写成配置文件

    package com.dcits.gatewayserver.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.cors.CorsConfiguration;
    import org.springframework.web.cors.reactive.CorsWebFilter;
    import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
    import org.springframework.web.util.pattern.PathPatternParser;
    
    @Configuration 
    public class CorsConfig { 
        @Bean
        public CorsWebFilter corsFilter() { 
            CorsConfiguration config = new CorsConfiguration(); 
            config.addAllowedMethod("*"); 
            config.addAllowedOrigin("*"); 
            config.addAllowedHeader("*"); 
            UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser()); 
            source.registerCorsConfiguration("/**", config); return new CorsWebFilter(source); 
        } 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    3.yml进行配置

    spring:
      application:
        name: gateway-server
      cloud:
        gateway:
          globalcors:
            corsConfigurations:
              '[/**]': #针对哪些路径
                allowCredentials: true # 这个是可以携带 cookie
                allowedHeaders: '*'
                allowedMethods: '*'
                allowedOrigins: '*'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
  • 相关阅读:
    【UML】浅谈为什么要有UML?
    【Vue 开发实战】基础篇 # 2:组件基础及组件注册
    通过STM32Cube配置完成基于I2C协议的AHT20温湿度传感器的数据采集
    Vue语法
    java毕业设计视频点播系统Mybatis+系统+数据库+调试部署
    459. 重复的子字符串
    UE集成第三方库开发技巧、自定义第三方库输出路径
    netty系列之:netty中的frame解码器
    2022年6月总结
    二叉树的一些基本操作
  • 原文地址:https://blog.csdn.net/YiRenGengShangBuQi/article/details/126839963