开发者社区> it菲菲> 正文

java版spring cloud+spring boot 社交电子商务平台--Spring cloud gateway限流

简介: 限流一般有两个实现方式,令牌桶和漏桶。 金牌桶是初始化令牌(容器)的个数,通过拿走里边的令牌就能通过, 没有令牌不能报错,可以设置向容器中增加令牌的速度和最大个数 漏桶是向里边放入请求,当请求数量达到最大值后,丢弃,漏桶中的数据以一定速度流出,没有则不流出 金牌桶实现方式如下: pom com.
+关注继续查看

限流一般有两个实现方式,令牌桶和漏桶。

金牌桶是初始化令牌(容器)的个数,通过拿走里边的令牌就能通过, 没有令牌不能报错,可以设置向容器中增加令牌的速度和最大个数

漏桶是向里边放入请求,当请求数量达到最大值后,丢弃,漏桶中的数据以一定速度流出,没有则不流出

金牌桶实现方式如下:

pom

<dependency>
    <groupId>com.github.vladimir-bukhtoyarov</groupId>
    <artifactId>bucket4j-core</artifactId>
    <version>4.0.0</version>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>

创建下边类并且继承下边类

public class LimitFilter implements GatewayFilter, Ordered {

    private final Logger logger = LoggerFactory.getLogger(LimitFilter.class);

    int capacity;
    int refillTokens;
    Duration refillDuration;

    public LimitFilter(int capacity, int refillTokens, Duration refillDuration) {
        this.capacity = capacity;
        this.refillTokens = refillTokens;
        this.refillDuration = refillDuration;
    }

    private static final Map<String,Bucket> CACHE = new ConcurrentHashMap<>();
    private Bucket createNewBucket() {
        Refill refill = Refill.of(refillTokens,refillDuration);
        Bandwidth limit = Bandwidth.classic(capacity,refill);
        return Bucket4j.builder().addLimit(limit).build();
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String ip = exchange.getRequest().getRemoteAddress().getAddress().getHostAddress();
        Bucket bucket = CACHE.computeIfAbsent(ip,k -> createNewBucket());
        logger.info("IP: " + ip + ",TokenBucket Available Tokens: " + bucket.getAvailableTokens());
        if (bucket.tryConsume(1)) {
            return chain.filter(exchange);
        } else {
            exchange.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
            return exchange.getResponse().setComplete();
        }

    }

    @Override
    public int getOrder() {
        return 0;
    }
}

配置路由

  @Bean
    public RouteLocator customerRouteLocator(RouteLocatorBuilder builder) {
// @formatter:off
        return builder.routes()
                .route(r -> r.path("/consulserver/**")
                        .filters(f -> f.stripPrefix(1)
                                .filter(new LimitFilter(10,1,Duration.ofSeconds(1))))
                        .uri("lb://consulserver")
                        .order(0)
                        .id("throttle_customer_service")
                ).build();
// @formatter:on

    } 

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
JSP - 起源、执行过程、运行原理、生命周期
JSP - 起源、执行过程、运行原理、生命周期
5 0
NLP比赛-小布助手对话短文本语义匹配
NLP比赛-小布助手对话短文本语义匹配
8 0
心中有“树”!图文并茂介绍数据结构中常见的树(一)
提到数据结构中的树(Tree) ,大家应该都不陌生,相关书籍中都有大段篇幅的介绍,刷 Leetcode 的时候会遇到很多相关问题。很多人往往会用 “手写红黑树” 来形容面试难度很高。
10 0
这个开源项目绝绝子,一键生成好玩的矢量风格头像!
最近逛 GitHub,发现了一个非常好玩的开源项目——头像生成器,给大家分享一下~
5 0
心中有“树”!图文并茂介绍数据结构中常见的树(三)
在前面两篇文章中,我们简要介绍了数据结构中的各种【树】在搜索、数据库等领域的使用场景,希望对大家有所帮助。
10 0
如何快速的做一个血条
本文主要内容:如何在小游戏制作工具中利用“遮罩”快速的实现一个血条。
7 0
+关注
it菲菲
欢迎大家一起讨论 springcloud 更多源码 一零三八七七四六二六
113
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
OceanBase 入门到实战教程
立即下载
阿里云图数据库GDB,加速开启“图智”未来.ppt
立即下载
实时数仓Hologres技术实战一本通2.0版(下)
立即下载