Spring Cloud Zuul网关详解与使用案例
一、Zuul
Zuul是Netflix开源的微服务网关组件,是Spring Cloud生态系统中的网关服务,主要功能包括:
- 动态路由:将请求动态路由到不同的微服务
- 请求过滤:实现权限校验、流量控制等功能
- 负载均衡:集成Ribbon实现客户端负载均衡
- 服务聚合:将多个服务调用聚合成一个接口返回
- 服务熔断:集成Hystrix实现熔断机制
二、Zuul核心概念
1. 过滤器(Filter)
Zuul的核心是过滤器,分为四种类型:
- PRE:在路由之前执行(认证、日志、限流)
- ROUTING:将请求路由到微服务
- POST:路由到微服务之后执行(响应头修改、收集统计信息)
- ERROR:发生错误时执行
2. 路由规则
通过配置将URL路径映射到具体的微服务
三、Zuul使用案例
1. 基础配置
1.1 添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
1.2 启用Zuul
@SpringBootApplication
@EnableZuulProxy
public class ZuulGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulGatewayApplication.class, args);
}
}
1.3 基本路由配置(application.yml)
zuul:
routes:
user-service: # 路由名称,可自定义
path: /user/** # 映射路径
serviceId: user-service # 服务名称(需注册到Eureka)
stripPrefix: false # 是否去除前缀
order-service:
path: /order/**
url: http://localhost:8081/ # 直接指定URL
2. 自定义过滤器示例
@Component
public class AuthFilter extends ZuulFilter {
// 过滤器类型
@Override
public String filterType() {
return "pre";
}
// 执行顺序,数字越小优先级越高
@Override
public int filterOrder() {
return 0;
}
// 是否执行该过滤器
@Override
public boolean shouldFilter() {
return true;
}
// 过滤器具体逻辑
@Override
public Object run() throws ZuulException {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
String token = request.getHeader("Authorization");
if (StringUtils.isEmpty(token)) {
ctx.setSendZuulResponse(false); // 不进行路由
ctx.setResponseStatusCode(401);
ctx.setResponseBody("未授权访问");
return null;
}
// 验证token逻辑...
return null;
}
}
3. 高级配置
3.1 路由排除
zuul:
ignored-services: '*' # 忽略所有自动发现的服务
ignored-patterns: /**/admin/** # 忽略特定路径
routes:
user-service:
path: /user/**
serviceId: user-service
3.2 前缀设置
zuul:
prefix: /api # 为所有路由添加前缀
strip-prefix: true # 是否去除前缀
3.3 熔断配置
@Bean
public ZuulFallbackProvider userServiceFallback() {
return new ZuulFallbackProvider() {
@Override
public String getRoute() {
return "user-service";
}
@Override
public ClientHttpResponse fallbackResponse() {
return new ClientHttpResponse() {
@Override
public HttpStatus getStatusCode() {
return HttpStatus.SERVICE_UNAVAILABLE;
}
@Override
public String getStatusText() {
return "SERVICE_UNAVAILABLE";
}
@Override
public void close() {}
@Override
public InputStream getBody() {
return new ByteArrayInputStream("用户服务不可用,请稍后再试".getBytes());
}
@Override
public HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return headers;
}
};
}
};
}
4. 结合Eureka实现服务发现
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
zuul:
routes:
user-service:
path: /user/**
serviceId: user-service # 会自动从Eureka发现服务
四、常见问题解决方案
- 跨域问题:可以通过配置CORS过滤器解决
- 文件上传问题:需要禁用Zuul的Servlet过滤器
- 敏感头信息:使用
sensitiveHeaders
配置不传递的Header - 性能监控:集成Spring Boot Actuator监控路由信息
五、Zuul与Gateway对比
| 特性 | Zuul | Spring Cloud Gateway |
|--------------|------|----------------------|
| 性能 | 一般 | 基于Netty,性能更好 |
| 异步支持 | 不支持 | 支持 |
| 过滤器功能 | 简单 | 更强大 |
| 维护状态 | 停止维护 | 官方推荐 |
虽然Spring Cloud Gateway是官方推荐的新一代网关,但Zuul在生产中仍有大量应用。
六、实践建议
- 将鉴权、日志等公共功能放在网关层
- 为不同环境配置不同的路由规则
- 合理使用过滤器链,避免过多复杂逻辑
- 结合Hystrix实现熔断降级
- 使用Actuator监控网关健康状态
通过以上配置和案例,可以快速搭建一个功能完善的API网关,为微服务架构提供统一的入口和安全保障。