spring cloud之网关限流

在高并发的系统中,往往需要在系统中做限流,一方面是为了防止大量的请求使服务器过载,导致服务不可用,另一方面是为了防止网络攻击

令牌算法

令牌桶算法能够在限制调用的平均速率的同时还允许一定程度的突发调用。在令牌桶算法中,存在一个桶,用来存放固定数量的令牌。算法中存在一种机制,以一定的速率往桶中放令牌。每次请求调用需要先获取令牌,只有拿到令牌,才有机会继续执行,否则选择选择等待可用的令牌、或者直接拒绝。放令牌这个动作是持续不断的进行,如果桶中令牌数达到上限,就丢弃令牌,所以就存在这种情况,桶中一直有大量的可用令牌,这时进来的请求就可以直接拿到令牌执行,比如设置qps为100,那么限流器初始化完成一秒后,桶中就已经有100个令牌了,这时服务还没完全启动好,等启动完成对外提供服务时,该限流器可以抵挡瞬时的100个请求。所以,只有桶中没有令牌时,请求才会进行等待,最后相当于以一定的速率执行。
在这里插入图片描述
令牌桶算法的实现由Google Guava的RateLimiter、Bucket4j、RateLimitJ ,他们支持的 back-ends为JCache、Hazelcast、Redis ,您可以根据自己的技术栈选择相应的实现

限流维度

IP地址、用户(token)、URI地址

POM依赖

// 网关jar
<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</artifactId>
</dependency>
spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: demo
          uri: lb://demo
          predicates:
            - Path=/demo/**
          filters:
            - StripPrefix=1
            # 限流过滤器,使用gateway内置令牌算法
            - name: RequestRateLimiter
              args:
                # 令牌桶每秒填充平均速率,即行等价于允许用户每秒处理多少个请求平均数
                redis-rate-limiter.replenishRate: 50
                # 令牌桶的容量,允许在一秒钟内完成的最大请求数
                redis-rate-limiter.burstCapacity: 100
                # 用于限流的键的解析器的Bean对象的名字
                #它使用 SpEL 表达式根据#{@beanName}从 Spring 容器中获取 Bean 对象。
                key-resolver: "#{@ipKeyResolver}"
import java.util.Objects;

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;

@Configuration
public class RequestRateLimiterConfig {

	@Primary
	@Bean
	KeyResolver ipKeyResolver() {
		// 按IP来限流
		return exchange -> Mono.just(Objects.requireNonNull(exchange.getRequest().getRemoteAddress()).getAddress().getHostAddress());
	}

	@Bean
	KeyResolver apiKeyResolver() {
		// 按URL限流
		return exchange -> Mono.just(exchange.getRequest().getPath().toString());
	}

	@Bean
	KeyResolver userKeyResolver() {
		// 按用户限流
		return exchange -> Mono.just(Objects.requireNonNull(exchange.getRequest().getHeaders().getFirst("Authorization")));
	}
}

以上就是代码层面的配置然后就可以实现服务级别的限流了

限流之后后端总要响应前端
后面就讲网关的熔断和服务降级

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值