Spring Cloud Gateway 过滤器之GlobalGilter和GatewayFilter初识

1、简介

GlobalGilter 全局过滤器接口与 GatewayFilter 网关过滤器接口具有相同的方法定义。全局过滤器是一系列特殊的过滤器,会根据条件应用到所有路由中。网关过滤器是更细粒度的过滤器,作用于指定的路由中。

查看GlobalGilter 的类图如下:

包括路由转发、负载均衡、ws 路由、netty 路由等全局过滤器,如需详细了解每个类需要自行百度。 

 

GlobalGilter的例子:

package com.zoo.gateway.filter;

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * @Author: xf
 * @Date: 2019/8/14 15:25
 * @Version 1.0
 */
@Component
public class TokenFilter implements GlobalFilter, Ordered {
    private static final boolean enableRateLimit = false;//开关

    @Override
    public int getOrder() {
        // -1 is response write filter, must be called before that
        return -2;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        if (!enableRateLimit) {
            return chain.filter(exchange);
        }
        ServerHttpRequest request = exchange.getRequest();
        String token = request.getQueryParams().getFirst("token");
        if (token == null || token.isEmpty()) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }
}
GatewayFilter的例子:
package com.zoo.gateway.filter;

import io.github.bucket4j.Bandwidth;
import io.github.bucket4j.Bucket;
import io.github.bucket4j.Bucket4j;
import io.github.bucket4j.Refill;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.text.SimpleDateFormat;
import java.time.Duration;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author: xf
 * @Date: 2019/8/14 15:38
 * @Version 1.0
 */
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class RateLimitByIpGatewayFilter implements GatewayFilter, Ordered {

    int capacity;//桶的最大容量,即能装载 Token 的最大数量
    int refillTokens;//每次 Token 补充量
    Duration refillDuration;//补充 Token 的时间间隔
    private static final Map<String, Bucket> CACHE = new ConcurrentHashMap<>();
    private static final boolean enableRateLimit = true;//开关

    private Bucket createNewBucket() {
        Refill refill = Refill.of(refillTokens, refillDuration);
        Bandwidth limit = Bandwidth.classic(capacity, refill);
        return Bucket4j.builder().addLimit(limit).build();
    }

    @Override
    public int getOrder() {
        return -2;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
         if (!enableRateLimit){
             return chain.filter(exchange);
         }
        String ip = exchange.getRequest().getRemoteAddress().getAddress().getHostAddress();
        Bucket bucket = CACHE.computeIfAbsent(ip, k -> createNewBucket());

        if (bucket.tryConsume(1)) {
            return chain.filter(exchange);
        } else {
            exchange.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
            return exchange.getResponse().setComplete();
        }
    }

//    public static void main(String[] args) {
//        Bandwidth limit = Bandwidth.simple(10, Duration.ofSeconds(1));
//        Bucket bucket = Bucket4j.builder().addLimit(limit).build();
//        if(bucket.tryConsume(1)){
//            System.out.println("do something");
//        }else{
//            System.out.println("do nothing");
//        }
//    }

    public static void main(String[] args) {
        Bandwidth limit = Bandwidth.simple(1, Duration.ofSeconds(1));
        Bucket bucket = Bucket4j.builder().addLimit(limit).build();
        while(true){
            if(bucket.tryConsume(1)){
                System.out.println(new SimpleDateFormat("HH:mm:ss").format(new Date()));
            }else{
                try{
                    System.out.println("waiting...");
                    Thread.sleep(200);
                }catch (Exception e){
                }
            }
        }
    }



}

。。。。。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值