Zuul的过滤器

Zuul过滤器简介

spring cloud Zuul包含了对请求的路由和过滤2个功能。路由功能负责将请求转发到具体的微服务上,而过滤器负责对请求的处理过程进行干预,是实现权限校验、服务聚合等功能的基础。

在实际运行时,路由映射和请求转发是由几个不同的过滤器完成的。每一个进入zuul的http请求都会经过一系列的过滤器处理链得到请求响应并返回给客户端。

spring cloud zuul包含4种类型的过滤器。

  • pre过滤器。在请求被路由之前调用。Zuul请求微服务之前。比如请求身份验证,选择微服务实例,记录调试信息等。
  • route过滤器。负责转发请求到微服务。原始请求在此构建,并使用Apache HttpClient或Netflix Ribbon发送原始请求。
  • post过滤器。在route和error过滤器之后被调用。可以在响应添加标准HTTP Header、收集统计信息和指标,以及将响应发送给客户端等。
  • error过滤器。在处理请求发生错误时被调用。

除了默认的Filter,Zuul还允许我们创建自定义的过滤器类型。比如,我们可以自定义一个STATIC类型的过滤器,它在Zuul中生成响应,而不是将请求转发给具体的微服务。

Zuul请求的生命周期如下:

mark

参考Netflix Zuul wiki

自定义Zuul过滤器

新建模块microservice-gateway-zuul-filter。

添加Zuul和Eureka客户端的依赖:

1
2
3
4
5
6
7
8
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>

application.yml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
spring:
  application:
    name: microservice-gateway-zuul-filter

server:
  port: 8809

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka
  instance:
    prefer-ip-address: true

zuul:
  routes:
    user1:
      path: /user/**
      serviceId: microservice-springcloud-user
      stripPrefix: false

logging:
  level:
    com.netflix: debug

定义一个pre类型的过滤器,记录请求的URI。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class MyZuulPreFilter extends ZuulFilter {
    private final static Logger LOGGER = org.slf4j.LoggerFactory.getLogger(MyZuulPreFilter.class);
    @Override
    public String filterType() {
        return "pre"; // 指定过滤器类型
    }

    @Override
    public int filterOrder() {
        return 0; // 过滤器顺序,数字越小越先执行
    }

    @Override
    public boolean shouldFilter() {
        return true; // 是否使用该过滤器。
    }

    // 过滤器具体执行的操作
    @Override
    public Object run() {
        HttpServletRequest request = RequestContext.getCurrentContext().getRequest();
        String requestUri = request.getRequestURI();
        LOGGER.info("请求的URI:{}",requestUri);
        return null;
    }
}

spring boot主类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@SpringBootApplication
@EnableZuulProxy
public class ZuulFilterApplication
{
    public static void main( String[] args )
    {
        SpringApplication.run(ZuulFilterApplication.class,args);
    }

    @Bean
    public MyZuulPreFilter myZuulPreFilter() {
        return new MyZuulPreFilter();
    }
}

测试:

启动Eureka Server、user模块和microservice-gateway-zuul-filter。

我们通过Zuul的host和port访问user模块的/sample/1.

mark

我们看下控制台。

mark

我们只是简单记录一下请求的URI。更多的用法可以参考netflix-core包中的ZuulFilter实现。

mark

Zuul过滤器的详细使用可以参考:https://www.jianshu.com/p/ff863d532767