微信登录

服务网关 - Zuul - 传统服务网关

Java - Web - Spring 《服务网关 - Zuul - 传统服务网关》

一、引言

在微服务架构中,服务的数量通常会不断增加。客户端需要与多个微服务进行交互,这就带来了一些问题,比如服务的路由、负载均衡、安全认证等。服务网关作为微服务架构中的重要组件,就像整个微服务系统的大门,负责统一处理客户端的请求,为客户端提供一个统一的入口。Zuul 是 Netflix 开源的一个基于 JVM 路由和服务端的负载均衡器,是传统服务网关的典型代表。本文将详细介绍 Zuul 的使用,包括基本概念、配置和演示代码。

二、Zuul 基本概念

2.1 核心功能

  • 路由:根据请求的 URL 将请求转发到不同的微服务。
  • 过滤:在请求到达微服务之前或之后执行一些预处理或后处理操作,比如身份验证、日志记录等。

2.2 过滤器类型

  • PRE:在请求被路由之前执行,可用于身份验证、日志记录等。
  • ROUTING:将请求路由到微服务。
  • POST:在请求被路由到微服务之后执行,可用于添加响应头、日志记录等。
  • ERROR:在请求处理过程中发生错误时执行。

三、搭建 Zuul 服务网关

3.1 创建 Spring Boot 项目

使用 Spring Initializr 创建一个新的 Spring Boot 项目,添加以下依赖:

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework.cloud</groupId>
  4. <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.springframework.boot</groupId>
  8. <artifactId>spring-boot-starter-web</artifactId>
  9. </dependency>
  10. </dependencies>

3.2 启用 Zuul

在主应用类上添加 @EnableZuulProxy 注解:

  1. import org.springframework.boot.SpringApplication;
  2. import org.springframework.boot.autoconfigure.SpringBootApplication;
  3. import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
  4. @SpringBootApplication
  5. @EnableZuulProxy
  6. public class ZuulGatewayApplication {
  7. public static void main(String[] args) {
  8. SpringApplication.run(ZuulGatewayApplication.class, args);
  9. }
  10. }

3.3 配置路由规则

application.properties 中配置路由规则:

  1. # 服务名映射到具体的服务地址
  2. zuul.routes.user-service.path=/user-service/**
  3. zuul.routes.user-service.url=http://localhost:8081
  4. zuul.routes.order-service.path=/order-service/**
  5. zuul.routes.order-service.url=http://localhost:8082

上述配置表示,所有以 /user-service 开头的请求将被转发到 http://localhost:8081,所有以 /order-service 开头的请求将被转发到 http://localhost:8082

四、自定义过滤器

4.1 创建过滤器类

创建一个自定义的 PRE 过滤器,用于在请求被路由之前进行日志记录:

  1. import com.netflix.zuul.ZuulFilter;
  2. import com.netflix.zuul.context.RequestContext;
  3. import com.netflix.zuul.exception.ZuulException;
  4. import org.slf4j.Logger;
  5. import org.slf4j.LoggerFactory;
  6. import javax.servlet.http.HttpServletRequest;
  7. public class LoggingFilter extends ZuulFilter {
  8. private static final Logger logger = LoggerFactory.getLogger(LoggingFilter.class);
  9. @Override
  10. public String filterType() {
  11. return "pre";
  12. }
  13. @Override
  14. public int filterOrder() {
  15. return 1;
  16. }
  17. @Override
  18. public boolean shouldFilter() {
  19. return true;
  20. }
  21. @Override
  22. public Object run() throws ZuulException {
  23. RequestContext ctx = RequestContext.getCurrentContext();
  24. HttpServletRequest request = ctx.getRequest();
  25. logger.info("Received request: {} {}", request.getMethod(), request.getRequestURL().toString());
  26. return null;
  27. }
  28. }

4.2 注册过滤器

在配置类中注册自定义过滤器:

  1. import org.springframework.context.annotation.Bean;
  2. import org.springframework.context.annotation.Configuration;
  3. @Configuration
  4. public class ZuulConfig {
  5. @Bean
  6. public LoggingFilter loggingFilter() {
  7. return new LoggingFilter();
  8. }
  9. }

五、测试 Zuul 网关

5.1 启动服务

启动 Zuul 网关服务以及模拟的 user-serviceorder-service

5.2 发送请求

使用浏览器或工具(如 Postman)发送请求:

  • 发送请求 http://localhost:8080/user-service/api/users,Zuul 网关会将该请求转发到 http://localhost:8081/api/users
  • 发送请求 http://localhost:8080/order-service/api/orders,Zuul 网关会将该请求转发到 http://localhost:8082/api/orders

同时,在控制台可以看到自定义过滤器记录的请求日志。

六、总结

6.1 Zuul 优点

  • 简单易用:通过简单的配置就可以实现路由和过滤功能。
  • 功能丰富:提供了多种过滤器类型,可以满足不同的业务需求。

6.2 Zuul 缺点

  • 性能问题:基于同步阻塞 I/O,在高并发场景下性能可能不如一些异步网关。
  • 维护问题:Netflix 已经停止对 Zuul 1.x 的维护。

6.3 对比表格

特性 Zuul 1.x
路由功能 支持基于 URL 的路由规则配置
过滤功能 提供 PRE、ROUTING、POST、ERROR 四种过滤器类型
性能 同步阻塞 I/O,高并发场景性能一般
维护情况 已停止维护

通过本文的介绍和演示代码,你应该对 Zuul 作为传统服务网关有了更深入的了解。虽然 Zuul 1.x 存在一些不足之处,但在一些中小规模的项目中仍然可以发挥重要作用。

希望本文对你理解和使用 Zuul 有所帮助!