0%

zuul简介

Zuul:微服务架构中的路由与过滤网关

Zuul 是 Netflix 开源的微服务网关组件,作为系统的 “入口网关”,负责请求的路由转发和过滤处理,是微服务架构中连接客户端与内部服务的关键中间层。

Zuul 的核心功能

Zuul 的核心价值体现在路由(Routing)过滤(Filtering) 两大功能:

路由(Routing)

将外部请求根据规则转发到对应的微服务实例,实现 “统一入口”。例如:

  • 客户端访问 http://zuul-gateway/dept/get/1,Zuul 将请求转发到 “部门服务”;
  • 访问 http://zuul-gateway/user/login,转发到 “用户服务”。

通过路由,客户端无需记住每个微服务的地址,只需访问 Zuul 网关即可。

过滤(Filtering)

在请求转发的全过程中插入自定义逻辑,实现安全校验、监控、限流等功能。例如:

  • 身份认证:拦截未登录请求,返回 401 错误;
  • 日志记录:记录所有请求的路径、耗时等信息;
  • 请求修改:统一添加请求头(如 X-Request-Id);
  • 限流熔断:限制某接口的请求频率,防止服务过载。

Zuul 的特性与局限性

特性

  • 基于 Servlet:采用传统的 Servlet 模型,同步阻塞处理请求;
  • 与服务发现集成:自动从 Eureka 等注册中心获取服务列表,动态更新路由;
  • 灵活的路由规则:支持自定义路径映射、前缀、忽略规则等;
  • 丰富的过滤机制:通过自定义过滤器干预请求生命周期的各个阶段。

局限性

  • 性能瓶颈:基于同步阻塞 IO 模型,高并发场景下可能成为系统瓶颈;
  • 不支持长连接:依赖 Servlet 2.5 规范,无法处理 WebSocket 等长连接请求;
  • 已停止更新:Netflix 已停止 Zuul 1.x 的开发,推荐使用 Spring Cloud Gateway 作为替代。

Zuul 的集成与配置

1. 引入依赖

根据 Spring Cloud 版本选择对应依赖:

  • Spring Cloud F 版及以上

    1
    2
    3
    4
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
    </dependency>
  • 旧版本(如 Edgware)

    1
    2
    3
    4
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zuul</artifactId>
    </dependency>

需同时添加服务发现依赖(如 Eureka Client),以便 Zuul 从注册中心获取服务信息。

2. 启动类配置

通过 @EnableZuulProxy 注解启用 Zuul 网关功能:

1
2
3
4
5
6
7
8
@SpringBootApplication
@EnableEurekaClient // 注册到服务中心
@EnableZuulProxy // 启用 Zuul 网关(包含路由和过滤功能)
public class ZuulGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulGatewayApplication.class, args);
}
}

3. 基础路由配置

Zuul 默认根据服务名自动生成路由规则(无需额外配置):

  • 微服务名:micro-service-dept,则默认路由为 http://zuul-ip:port/micro-service-dept/**

若需自定义路由规则,在 application.yml 中配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
zuul:
routes:
# 路由规则1:将 /deptService/** 映射到 micro-service-dept 服务
deptService:
serviceId: micro-service-dept # 目标服务名(从注册中心获取)
path: /deptService/** # 匹配的路径
# 路由规则2:直接路由到外部URL(非微服务)
externalService:
url: http://api.example.com/ # 目标URL
path: /external/** # 匹配路径
ignored-services: micro-service-dept # 禁用默认服务名路由(仅允许自定义路由访问)
prefix: /api # 全局路径前缀(所有请求需加 /api 前缀)
ignored-patterns: /deptService/delete/** # 忽略特定路径(不转发)

访问示例
配置后,访问 http://localhost:9527/api/deptService/dept/get/1,会转发到 micro-service-dept 服务的 /dept/get/1 接口。

4. 敏感头信息处理

Zuul 默认会过滤掉敏感头信息(如 CookieSet-CookieAuthorization),防止跨服务传递。若需允许传递,配置:

1
2
3
4
5
6
7
8
zuul:
routes:
deptService:
serviceId: micro-service-dept
path: /deptService/**
sensitive-headers: # 空值表示不过滤任何头信息(允许所有头传递)
# 全局配置(对所有服务生效)
sensitive-headers:

Zuul 过滤器:自定义请求处理

Zuul 的过滤器是其核心扩展点,通过继承 ZuulFilter 可实现自定义逻辑。过滤器按执行阶段分为四类:

过滤器类型 执行时机 作用示例
PRE 请求被路由前 身份认证、参数校验
ROUTING 请求被路由时 选择路由目标、修改请求
POST 请求被路由后,返回响应前 添加响应头、日志记录
ERROR 请求处理过程中发生错误时 错误统一处理

自定义过滤器示例(PRE 类型,身份认证)

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
27
28
29
30
31
32
33
@Component
public class AuthFilter extends ZuulFilter {
@Override
public String filterType() {
return "pre"; // 前置过滤器
}

@Override
public int filterOrder() {
return 1; // 执行顺序(数值越小越先执行)
}

@Override
public boolean shouldFilter() {
return true; // 是否启用过滤器(true 表示启用)
}

@Override
public Object run() throws ZuulException {
// 获取请求上下文
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();

// 校验 token
String token = request.getParameter("token");
if (token == null || !"valid-token".equals(token)) {
ctx.setSendZuulResponse(false); // 阻止路由
ctx.setResponseStatusCode(401); // 返回 401 未授权
ctx.setResponseBody("Unauthorized: missing or invalid token");
}
return null;
}
}

生效条件

  • 过滤器需被 Spring 容器扫描(添加 @Component);
  • shouldFilter() 返回 true 时,过滤器才会执行。

Zuul 的高可用配置

Zuul 作为网关,需避免单点故障,可通过以下方式实现高可用:

  1. 多实例部署:启动多个 Zuul 实例,注册到服务中心;
  2. 负载均衡:客户端通过服务名(如 zuul-gateway)访问,由 Eureka + Ribbon 自动负载均衡;
  3. 熔断降级:集成 Hystrix,当后端服务故障时返回降级响应:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
zuul:
routes:
deptService:
serviceId: micro-service-dept
path: /deptService/**
retryable: false # 关闭重试(避免重试加剧服务压力)

# 配置 Hystrix 超时(防止 Zuul 线程阻塞)
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 3000 # 超时时间 3 秒

# 配置 Ribbon 超时(需小于 Hystrix 超时)
ribbon:
ReadTimeout: 2000
ConnectTimeout: 1000

总结

Zuul 作为早期微服务网关的代表,通过路由和过滤功能实现了客户端与微服务的解耦,简化了系统入口管理。尽管存在性能瓶颈和停止更新的问题,但其设计思想(如过滤器模式、服务发现集成)对理解网关组件具有重要意义。

在实际项目中,若需更高性能和异步支持,推荐使用 Spring Cloud Gateway 替代 Zuul

欢迎关注我的其它发布渠道

表情 | 预览
快来做第一个评论的人吧~
Powered By Valine
v1.3.10