Spring Cloud服务入口Gateway的自定义过滤新径

1周前发布 gsjqwyl
13 0 0

文章标题:

Spring Cloud中Gateway服务入口的自定义过滤新方式

文章内容:

目录

过滤器执行顺序

在一个项目里,如果同时存在GatewayFilter和GlobalFilter,它们的执行顺序是怎样的呢?当请求完成路由后,网关会把项目中的GatewayFilter和GlobalFilter合并到一个过滤器链(集合)中,然后进行排序,依次执行这些过滤器。

每一个过滤器都得指定一个int类型的order值,默认是0,这代表该过滤的优先级。order值越小,优先级越高,执行顺序就越靠前。

  • Filter能够通过实现Order接口或者添加@Order注解来指定order值。
  • Spring Cloud Gateway提供的Filter由Spring来指定,用户自定义的Filter则由用户自己指定。
  • 当过滤器的order值相同时,执行顺序会是defaultFilter > GatewayFilter > GlobalFilter。

自定义过滤器

Spring Cloud Gateway为过滤器提供了扩展功能,开发者能够依据实际业务来自定义过滤器,自定义过滤器同样支持GatewayFilter和GlobalFilter两种类型。

自定义GatewayFilter

自定义GatewayFilter时,需要去实现对应的GatewayFilterFactory接口,Spring Boot默认帮我们实现了抽象类AbstractGatewayFilterFactory,我们可以直接使用。

定义GatewayFilter
package gateway;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Slf4j
@Component
public class CustomGatewayFilterFactory extends AbstractGatewayFilterFactory<CustomConfig> implements Ordered {
    public CustomGatewayFilterFactory() {
        super(CustomConfig.class);
    }

    @Override
    public GatewayFilter apply(CustomConfig config) {
        return new GatewayFilter() {
            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                log.info("Pre Filter, config:{} ",config); 
                return chain.filter(exchange).then(Mono.fromRunnable(()->{
                    log.info("Post Filter...."); 
                }));
            }
        };
    }

    @Override
    public int getOrder() {
        return Ordered.LOWEST_PRECEDENCE;
    }
}

针对这个Filter的配置,使用CustomConfig来定义:

package gateway;

import lombok.Data;

@Data
public class CustomConfig {
    private String name;
}

代码说明:

  1. 类名统一以GatewayFilterFactory结尾,默认情况下,过滤器的name会采用该定义类的前缀,这里的name是Custom(在yml配置中使用)。
  2. apply方法中同时包含Pre和Post过滤,then方法里是请求执行结束之后处理的逻辑。
  3. CustomConfig是一个配置类,该类只有一个属性name,和yml的配置相对应。
  4. 该类需要交给Spring管理,所以要加@Service注解。
  5. getOrder表示该过滤器的优先级,值越大,优先级越低。
配置过滤器
spring:
  cloud:
    gateway:
      routes:
        - id: order-service   #路由规则id,随便起,不重复即可
          uri: lb://order-service/ #目标服务地址
          predicates:   #路由条件
            - Path=/order/**,/feign/**
          filters:
            - AddRequestParameter=userName, xiaoming
            - name: Custom    #过滤器名称
              args:
                name: test_custom
启动服务并访问


自定义GlobalFilter

GlobalFilter的实现比较简单,它不需要额外的配置,只需要实现GlobalFilter接口,就会自动过滤所有的请求。

定义GlobalFilter
package gateway;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Slf4j
@Component
public class CustomGlobalFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("Pre Global Filter");
        return chain.filter(exchange).then(Mono.fromRunnable(()->{
            log.info("Post Global Filter...");
        }));
    }

    @Override
    public int getOrder() {
        return Ordered.LOWEST_PRECEDENCE;
    }
}
启动服务并访问


从日志中能够看出,当GatewayFilter和GlobalFilter过滤器的order一样时,会先执行GatewayFilter,然后再执行GlobalFilter。其中会先执行Pre GatewayFilter,接着执行Pre GlobalFilter,然后执行Post GlobalFilter,最后执行Post GatewayFilter。

服务部署

  1. 修改数据库、Nacos等相关配置。
  2. 对三个服务进行打包:product-service、order-service、gateway。
  3. 把jar上传到Linux服务器。
  4. 启动Nacos,启动前最好把data数据删除掉。
  5. 启动服务
#后台启动order-service,并设置输出日志到logs/order.log  
nohup java -jar order-service.jar >logs/order.log &

#后台启动product-service,并设置输出日志到logs/order.log  
nohup java -jar product-service.jar >logs/product-9090.log &

#启动网关  
nohup java -jar gateway.jar >logs/gateway.log &



观察日志:

© 版权声明

相关文章

没有相关内容!

暂无评论

none
暂无评论...