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