【Spring Cloud系列】Spring Cloud-网关Zuul详解与实战

本文涉及的产品
应用型负载均衡 ALB,每月750个小时 15LCU
传统型负载均衡 CLB,每月750个小时 15LCU
网络型负载均衡 NLB,每月750个小时 15LCU
简介: 笔记

一、概述


Spring Cloud Zuul 是 Spring Cloud Netflix 子项目的核心组件之一,是netflix开源的一个API Gateway服务器,本质上有一个Web Servlet应用,可以作为微服务架构中的 API 网关使用,支持动态路由与过滤功能;网关为微服务提供统一的访问入口;网关的定义类似设计模式中的门面模式,相当于微服务中的门面,客户端访问微服务都是通过它进行路由及过滤。它提供请求路由,负载均衡、校验过滤、服务容错、服务聚合等功能。


二、 Zuul功能和作用


Zuul可以通过加载动态过滤机制,从而实现以下各项功能:

▪验证与安全保障: 识别面向各类资源的验证要求并拒绝那些与要求不符的请求。

▪审查与监控: 在边缘位置追踪有意义数据及统计结果,从而为我们带来准确的生产状态结论。

▪路由转发: 以动态方式根据需要将请求路由至不同后端集群处。

▪压力测试: 逐渐增加指向集群的负载流量,从而计算性能水平。

▪负载均衡: 为每一种负载类型分配对应容量,并弃用超出限定值的请求。

▪静态响应处理: 在边缘位置直接建立部分响应,从而避免其流入内部集群。

▪多区域弹性: 跨越AWS区域进行请求路由,旨在实现ELB使用多样化并保证边缘位置与使用者尽可能接近。


除以上功能之外,Netflix公司还利用Zuul的功能通过金丝雀版本实现精确路由与压力测试。

在Spring Cloud中,可用通过添加Zuul的依赖和配置文件,快速搭建一个网关,方便统一管理和维护各个微服务,实现更好的服务治理。


三、Zuul网关工作原理


3.1 网关主要组件:

Zuul网关主要由一下几个组件构成:


▪Filter:过滤器,可以在请求被路由前或者之后添加一些处理逻辑。

▪Route:路由,将请求路由到不同的后端服务上。

▪Ribbon:负载均衡器,Zuul 默认使用 Ribbon 进行负载均衡。

▪Hystrix:容错处理器,可以实现限流和熔断机制。

Zuul 的过滤器链是整个网关的核心部分,它由多个过滤器构成,每个过滤器都负责不同的处理逻辑,比如请求的鉴权、转发等操作。过滤器链在处理请求的过程中,会依次执行这些过滤器,从而实现对请求的全生命周期管理,具体流程如下图所示。

在图中,我们可以看到 Filter Chain 主要由三部分组成:过滤器、生成路由并发送给后端服务、处理路由响应。下面我们将详细介绍每个部分的处理逻辑。


3.2 Zuul过滤器

过滤器是 Zuul 中最重要的组件之一,它可以拦截和修改请求和响应的内容,实现各种功能。在 Spring Cloud 中,所有的过滤器都必须继承抽象类 ZuulFilter,并实现其中的四个方法:

▪filterType()方法:返回过滤器类型,包括 pre、post、route 和 error 四种类型。

▪filterOrder()方法:返回过滤器执行的顺序,值越小越先执行。

▪shouldFilter()方法:判断过滤器是否需要执行,默认返回 true,表示全部需要执行。

▪run()方法:过滤器的主要业务逻辑,实现具体的过滤逻辑


Filter 类型

Zuul 中不同类型 filter 的执行逻辑核心在 com.netflix.zuul.http.ZuulServlet 类中定义,该类相关代码如下:

@Override
public void service(javax.servlet.ServletRequest servletRequest, javax.servlet.ServletResponse servletResponse) throws ServletException, IOException {
    try {
        init((HttpServletRequest) servletRequest, (HttpServletResponse) servletResponse);
        // Marks this request as having passed through the "Zuul engine", as opposed to servlets
        // explicitly bound in web.xml, for which requests will not have the same data attached
        RequestContext context = RequestContext.getCurrentContext();
        context.setZuulEngineRan();
        try {
            preRoute();
        } catch (ZuulException e) {
            error(e);
            postRoute();
            return;
        }
        try {
            route();
        } catch (ZuulException e) {
            error(e);
            postRoute();
            return;
        }
        try {
            postRoute();
        } catch (ZuulException e) {
            error(e);
            return;
        }
    } catch (Throwable e) {
        error(new ZuulException(e, 500, "UNHANDLED_EXCEPTION_" + e.getClass().getName()));
    } finally {
        RequestContext.getCurrentContext().unset();
    }
}

3.jpeg

这张经典的官方流程图有些问题,其中 post Filter 抛错之后进入 error Filter,然后再进入 post Filter 是有失偏颇的。实际上 post Filter 抛错分两种情况:

1.在 post Filter 抛错之前,pre、route Filter 没有抛错,此时会进入 ZuulException 的逻辑,打印堆栈信息,然后再返回 status = 500 的 ERROR 信息。

2.在 post Filter 抛错之前,pre、route Filter 已有抛错,此时不会打印堆栈信息,直接返回status = 500 的 ERROR 信息。

这样就比较直观地描述了 Zuul 关于 Filter 的请求生命周期。Zuul 中一共有四种不同生命周期的 Filter,分别是:

1.pre:在 Zuul 按照规则路由到下级服务之前执行。如果需要对请求进行预处理,比如鉴权、限流等,都应考虑在此类 Filter 实现。

2.route:这类 Filter 是 Zuul 路由动作的执行者,是 Apache Http Client 或 Netflix Ribbon 构建和发送原始 HTTP 请求的地方,目前已支持 Okhttp。

3.post:这类 Filter 是在源服务返回结果或者异常信息发生后执行的,如果需要对返回信息做一些处理,则在此类 Filter 进行处理。

4.error:在整个生命周期内如果发生异常,则会进入 error Filter,可做全局异常处理。


实际项目中,需要自实现以上类型的 Filter 来对请求链路进行处理,根据业务的需求,选取相应生命周期的 Filter 来达成目的。在 Filter 之间,通过 com.netflix.zuul.context.RequestContext 类来进行通信,内部采用 ThreadLocal 保存每个请求的一些信息,包括请求路由、错误信息、HttpServletRequest、HttpServletResponse,这使得一些操作是十分可靠的,它还扩展了 ConcurrentHashMap,目的是为了在处理过程中保存任何形式的信息。


3.3 生成路由并发送给后端服务

在Zuul中,可以通过配置ZuulProperties和RouteLocator实现路由转发的功能。其中ZuulProperties主要用于配置Zuul服务的一些相关属性,比如缓存时间、URL的前缀和后缀等;而RouteLocator则用于定义多个路由规则,将请求映射到不同的后端服务上。


当请求进入Zuul网关之后,首先会经过一系列过滤器处理,然后根据路由规则将请求转发到对应的后端服务上,最终返回响应结果。在转发请求时,Zuul可以自动地根据负载均衡策略选择相应的服务器,实现负载均衡的功能。


3.4 处理路由响应

在Zuul中,如果后端服务响应异常或者错误,那么 Zuul 会将这个异常封装成一个 ZuulException 对象,并交给其它的过滤器进行处理。当所有过滤器执行完毕之后,Zuul 会根据 ZuulException 中的状态码和错误消息,返回相应的响应结果。


四、Zuul 网关配置过程


在 Spring Cloud 中,我们可以通过添加一些依赖和配置文件,快速地创建一个 Zuul 网关服务。下面我们将详细介绍如何进行配置。


4.1 添加pom.xml依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

4.2 创建配置类

创建一个配置类,用于配置 Zuul 网关服务的相关属性。

@Configuration
@EnableZuulProxy
public class ZuulConfig {
    // 配置 Zuul 网关服务的相关属性
}

其中注解 @EnableZuulProxy 表示开启 Zuul 的代理功能,可以自动注册到 Eureka 服务中心,并集成 Ribbon 和 Hystrix 等组件。


4.3 配置路由规则

接下来我们需要配置 Zuul 的路由规则,将请求转发到不同的后端服务上。

@Bean
public RouteLocator routeLocator(RouteLocatorBuilder builder) {
    return builder.routes()
        .route("service-a", r -> r.path("/service-a/**")
            .filters(f -> f.stripPrefix(1))
            .uri("http://localhost:6060"))
        .route("service-b", r -> r.path("/service-b/**")
            .filters(f -> f.stripPrefix(1))
            .uri("http://localhost:6061"))
        .build();
}

在上面的代码中,我们定义了两个路由规则,分别将请求转发到 http://localhost:8081 和 http://localhost:8082 这两个地址上。其中 stripPrefix(1) 表示去掉 URL 中第一个斜杠之后的内容。


4.4 配置路由规则

最后我们可以添加一些过滤器,实现不同的功能。

@Bean
public MyFilter myFilter() {
    return new MyFilter();
}

其中 MyFilter 是我们自定义的过滤器类,用于实现一些特定的功能。


四、总结


本文从 Zuul 网关的原理、使用场景和配置过程三个方面详细介绍了 Zuul 网关的相关知识。可以看出,Zuul 的过滤器链是整个网关的核心部分,通过添加不同的过滤器,可以实现不同的功能,比如鉴权、转发、限流等。同时,通过合理地配置路由规则,可以将请求快速地转发到相应的后端服务中,实现负载均衡和服务治理的功能。


在实际开发中,我们可以根据不同的需求,灵活地运用 Zuul 网关服务,构建高可用、高并发的分布式应用系统。


相关实践学习
小试牛刀,一键部署电商商城
SAE 仅需一键,极速部署一个微服务电商商城,体验 Serverless 带给您的全托管体验,一起来部署吧!
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
目录
相关文章
|
8天前
|
人工智能 自然语言处理 前端开发
Spring AI与DeepSeek实战二:打造企业级智能体
本文介绍如何基于Spring AI与DeepSeek模型构建企业级多语言翻译智能体。通过明确的Prompt设计,该智能体能自主执行复杂任务,如精准翻译32种ISO标准语言,并严格遵循输入格式和行为限制。代码示例展示了如何通过API实现动态Prompt生成和翻译功能,确保服务的安全性和可控性。项目已开源,提供更多细节和完整代码。 [GitHub](https://github.com/zlt2000/zlt-spring-ai-app) | [Gitee](https://gitee.com/zlt2000/zlt-spring-ai-app)
104 11
|
15天前
|
人工智能 Java API
Spring AI与DeepSeek实战一:快速打造智能对话应用
在 AI 技术蓬勃发展的今天,国产大模型DeepSeek凭借其低成本高性能的特点,成为企业智能化转型的热门选择。而Spring AI作为 Java 生态的 AI 集成框架,通过统一API、简化配置等特性,让开发者无需深入底层即可快速调用各类 AI 服务。本文将手把手教你通过spring-ai集成DeepSeek接口实现普通对话与流式对话功能,助力你的Java应用轻松接入 AI 能力!虽然通过Spring AI能够快速完成DeepSeek大模型与。
321 11
|
22天前
|
前端开发 Java Nacos
🛡️Spring Boot 3 整合 Spring Cloud Gateway 工程实践
本文介绍了如何使用Spring Cloud Alibaba 2023.0.0.0技术栈构建微服务网关,以应对微服务架构中流量治理与安全管控的复杂性。通过一个包含鉴权服务、文件服务和主服务的项目,详细讲解了网关的整合与功能开发。首先,通过统一路由配置,将所有请求集中到网关进行管理;其次,实现了限流防刷功能,防止恶意刷接口;最后,添加了登录鉴权机制,确保用户身份验证。整个过程结合Nacos注册中心,确保服务注册与配置管理的高效性。通过这些实践,帮助开发者更好地理解和应用微服务网关。
75 0
🛡️Spring Boot 3 整合 Spring Cloud Gateway 工程实践
|
27天前
|
JavaScript 前端开发 Java
Jeesite5:Star24k,Spring Boot 3.3+Vue3实战开源项目,架构深度拆解!让企业级项目开发效率提升300%的秘密武器
Jeesite5 是一个基于 Spring Boot 3.3 和 Vue3 的企业级快速开发平台,集成了众多优秀开源项目,如 MyBatis Plus、Bootstrap、JQuery 等。它提供了模块化设计、权限管理、多数据库支持、代码生成器和国际化等功能,极大地提高了企业级项目的开发效率。Jeesite5 广泛应用于企业管理系统、电商平台、客户关系管理和知识管理等领域。通过其强大的功能和灵活性,Jeesite5 成为了企业级开发的首选框架之一。访问 [Gitee 页面](https://gitee.com/thinkgem/jeesite5) 获取更多信息。
Jeesite5:Star24k,Spring Boot 3.3+Vue3实战开源项目,架构深度拆解!让企业级项目开发效率提升300%的秘密武器
|
2月前
|
人工智能 安全 Java
AI 时代:从 Spring Cloud Alibaba 到 Spring AI Alibaba
本次分享由阿里云智能集团云原生微服务技术负责人李艳林主讲,主题为“AI时代:从Spring Cloud Alibaba到Spring AI Alibaba”。内容涵盖应用架构演进、AI agent框架发展趋势及Spring AI Alibaba的重磅发布。分享介绍了AI原生架构与传统架构的融合,强调了API优先、事件驱动和AI运维的重要性。同时,详细解析了Spring AI Alibaba的三层抽象设计,包括模型支持、工作流智能体编排及生产可用性构建能力,确保安全合规、高效部署与可观测性。最后,结合实际案例展示了如何利用私域数据优化AI应用,提升业务价值。
238 4
|
3月前
|
消息中间件 监控 Java
如何将Spring Boot + RabbitMQ应用程序部署到Pivotal Cloud Foundry (PCF)
如何将Spring Boot + RabbitMQ应用程序部署到Pivotal Cloud Foundry (PCF)
57 6
|
3月前
|
Java 关系型数据库 MySQL
如何将Spring Boot + MySQL应用程序部署到Pivotal Cloud Foundry (PCF)
如何将Spring Boot + MySQL应用程序部署到Pivotal Cloud Foundry (PCF)
92 5
|
3月前
|
缓存 监控 Java
如何将Spring Boot应用程序部署到Pivotal Cloud Foundry (PCF)
如何将Spring Boot应用程序部署到Pivotal Cloud Foundry (PCF)
73 5
|
9月前
|
消息中间件 Java 持续交付
Spring Cloud Alibaba 项目搭建步骤和注意事项
Spring Cloud Alibaba 项目搭建步骤和注意事项
995 0
Spring Cloud Alibaba 项目搭建步骤和注意事项
|
10月前
|
Java 中间件 开发者
Spring Cloud Alibaba
【1月更文挑战第27天】【1月更文挑战第127篇】Spring Cloud Alibaba
167 1