GateWay三大案例组件

一、局部过滤器接口耗时(LogTime)

  1. 命名规则:以GatewayFilterFactory结尾
  2. 编写接口耗时过滤器
java 复制代码
@Slf4j
@Component
public class LogTimeGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {

    private static long timeSpan = 0;
    @Override
    public GatewayFilter apply(NameValueConfig config) {
        String timeSpanStr = config.getValue();
        timeSpan = Long.valueOf(timeSpanStr);
        return new GatewayFilter() {
            @Override
            public Mono<Void> filter(ServerWebExchange exchange,  GatewayFilterChain chain) {

                long startTime = System.currentTimeMillis();
                return chain.filter(exchange).then(Mono.fromRunnable(()->{
                    long endTime = System.currentTimeMillis();
                    long time =  endTime-startTime;
                    if(time >= timeSpan){
                        log.debug("{} 耗时:{}",exchange.getRequest().getURI(), time);
                    }
                }));
            }
        };
    }
}
  1. 在yml文件中加入耗时时长

二、全局Token认证(TokenGlobalFilter)

目的是对所有进入系统的请求或相应进行统一处理

  1. 创建过滤器类
java 复制代码
@Slf4j
@Component
public class TokenFilter implements GlobalFilter, Ordered {
    @Value("${cn.smart.tokenx.key}")
    private String tokenKey;
    private static List<String> whiteList = CollUtil.newArrayList("/api/login", "/api/register");
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        URI uri = request.getURI();
        String path = uri.getPath().toLowerCase().trim();
        //排除白名单的验证
        if(whiteList.contains(path)){
            return chain.filter(exchange);
        }
        ServerHttpResponse response = exchange.getResponse();
        List<String> tokens = request.getHeaders().get("token");
        //验证的是有没有传token
        if(ObjectUtil.isEmpty(tokens)){
          log.error("请传token");
         response.setStatusCode(HttpStatus.UNAUTHORIZED);
          return response.setComplete();
        }
        String token = tokens.get(0);
        //验证的是传的token值是否为空
        if(ObjectUtil.isEmpty(token)){
            log.error("token 不能为空");
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }
        boolean b = false;
        // 验证算法,JWTValidator包含过期的验证,验证比较全面
        try {
         JWTValidator.of(token).validateAlgorithm(JWTSignerUtil.hs256(tokenKey.getBytes())).validateDate();
            b = true;
        }catch (Exception ex){
            ex.printStackTrace();
            log.error("token不正确");
        }
        if(!b){
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }
        //接着执行下面的过滤器,token还会带到下游,我们的服务还是要用我们之前的token-starter,token-starter功能只保留解析token写入Threadlocal,验证的功能不再需要
        return chain.filter(exchange);
    }
    @Override
    public int getOrder() {
        return 2;
    }
}
  1. 注册全局过滤器,使用@Component注解,Spring会自动扫描并注册Bean

三、全局链路跟踪TraceId日志(TraceIdGlobalFilter)

  1. 创建全局过滤器,在请求头上带入traceId参数,穿透到下游服务
java 复制代码
@Component
@Slf4j
@Order(1)
public class TraceIdFilter implements GlobalFilter {
    private static final  String  TRACE_ID = "traceId";

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        List<String> traceIds = request.getHeaders().get(TRACE_ID);
         if(ObjUtil.isNotEmpty(traceIds)){
             return chain.filter(exchange);
         }
        String traceId = IdUtil.simpleUUID();
        //request.getHeaders().set(TRACE_ID,traceId); //ReadOnlyHttpHeaders UnsupportedOperationException
        ServerHttpRequest request2 = request.mutate().header(TRACE_ID,traceId).build();
        return chain.filter(exchange.mutate().request(request2).build());
    }
  1. 下游服务使用全链路跟踪Id,配置TraceId过滤器
  2. 启动类开启SercletComponentScan扫描,启动类上加一个@SercletComponentScan注解
  3. 配置文件配置日志输出格式
相关推荐
小小小小关同学3 小时前
【Gateway】Gateway Filter Factories
网络·gateway
两仪式quq3 小时前
服务网关Gateway快速入门
服务器·网络·gateway
szc17672 天前
Gateway学习笔记
笔记·学习·gateway
huaqianzkh5 天前
什么是API网关(API Gateway)?
架构·gateway
亚林瓜子5 天前
Spring Cloud Gateway中的常见配置
spring·spring cloud·gateway
c1tenj25 天前
SpringCloud gateway
gateway
潘多编程5 天前
Gateway Timeout504: 网关超时的完美解决方法
gateway
lamb张5 天前
nginx搭配gateway的集群配置
网络·nginx·gateway
普通网友6 天前
spring-cloud-kubernetes与SpringCloud Gateway
spring cloud·kubernetes·gateway
java皮皮虫6 天前
SpringBoot2.7 + Nacos + GateWay
gateway·gateway过滤器