springcloud-getway搭建并且实现redisRequestRateLimiter限流

在搭建前,我们需要了解一下springcloud-getway限流的策略:
有计算器算法、漏桶算法、令牌桶算法;
Spring Cloud Gateway限流
我搭建了两台服务器,一台是getway 一台是demo,我的想法是通过getway去调用demo服务器
在这里插入图片描述

getway 服务器搭建:
引入getway jar

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.8.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.study</groupId>
    <artifactId>spring-cloud-getway</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-cloud-getway</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR3</spring-cloud.version>
    </properties>

    <dependencies>
        <!--getway网关-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <!--限流 redis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
            <version>2.0.5.RELEASE</version>
        </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>

    <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>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/libs-milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

这里我们需要注意的地方是:
springboot的版本号和spring-boot-starter-data-redis-reactive的版本号;
我这里使用的是springboot 2.1.8 的,如果版本号是2.2以上的spring-boot-starter-data-redis-reactive的版本号也要做好调整不然启动会报错;

配置文件application.yml:

server:
  port: 9000
spring:
  main:
    allow-bean-definition-overriding: true
  cloud:
    gateway:
      routes:
        - id: first_route #自定义id
          uri: http://192.168.0.74:8080 #ָip转发服务器ip
          predicates:
            - Path=/demo/** #请求路径
          filters:
            - name: RequestRateLimiter
              args:
                # 令牌桶每秒填充平均速率, 允许用户每秒处理多少个请求。
                redis-rate-limiter.replenishRate: 1
                # 令牌桶的容量,允许在1s内完成的最大请求数。
                redis-rate-limiter.burstCapacity: 2
                # 使用SpEL表达式从Spring容器中获取Bean对象, 查看RateLimiteConfig实现类中的方法名
                key-resolver: "#{@pathKeyResolver}"
                #key-resolver: "#{@ipKeyResolver}"
                #key-resolver: "#{@userKeyResolver}"
  application:
    name: gateway-limiter
  redis:
    host: 192.168.0.75
    port: 6379
    password: 123456
    database: 0
    timeout: 1800000

配置RateLimiteConfig文件

package com.study.config;

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

/**
 * 限流配置KeyResolver——有三种写法(接口限流/ip限流/用户限流)
 */
@Configuration
public class RateLimiteConfig {

    /**
     * 接口限流:根据请求路径限流
     * @return
     */
    /*
         如果不使用@Primary注解,会报如下错误,需要注意
    Description:
    Parameter 1 of method requestRateLimiterGatewayFilterFactory in org.springframework.cloud.gateway.config.GatewayAutoConfiguration required a single bean, but 3 were found:
            - pathKeyResolver: defined by method 'pathKeyResolver' in class path resource [com/mkevin/gateway/config/RateLimiteConfig.class]
            - ipKeyResolver: defined by method 'ipKeyResolver' in class path resource [com/mkevin/gateway/config/RateLimiteConfig.class]
            - userKeyResolver: defined by method 'userKeyResolver' in class path resource [com/mkevin/gateway/config/RateLimiteConfig.class]
    Action:
    Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier
    to identify the bean that should be consumed
    */
    @Bean
    @Primary
    public KeyResolver pathKeyResolver() {
        //写法1
        return exchange -> Mono.just(
                exchange.getRequest()
                        .getPath()
                        .toString()
        );

        /*
        //写法2
        return new KeyResolver() {
            @Override
            public Mono<String> resolve(ServerWebExchange exchange) {
                return Mono.just(exchange.getRequest()
                        .getPath()
                        .toString());
            }
        };
        */
    }

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

    /**
     * 根据请求参数中的userId进行限流
     *
     * 请求地址写法:http://localhost:8801/rate/123?userId=lisi
     *
     * @return
     */
    @Bean
    public KeyResolver userKeyResolver() {
        return exchange -> Mono.just(
                exchange.getRequest()
                        .getQueryParams()
                        .getFirst("userId")
        );
    }
}

从RateLimiteConfig 配置文件中可以清晰的看出,getaway的限流策略:对路径的限流,对ip限流,对参数限流。这些方式都可以在后面我们实现秒杀的时候其他一定的帮助;
为什么会引入redis呢?
在我们做压力测试的时候,并发量超过我们设置的阈值的时候,会把 错误信息存储到redis中
在这里插入图片描述
RequestRateLimiter是使用Redis来进行限流的,并在redis中存储了2个key

另一台服务demo搭建:
主要是接口路径:
在这里插入图片描述
我们可以清楚的看到getway服务器在application.yml中配置了
demo的服务器ip已经请求路径
在这里插入图片描述
限流配置:
在这里插入图片描述
这里采用的是令牌桶算法,配置方式都写了备注;

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值