Yang's blog Yang's blog
首页
Java
密码学
机器学习
命令手册
关于
友链
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

xiaoyang

编程爱好者
首页
Java
密码学
机器学习
命令手册
关于
友链
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • SpringCloud

    • 微服务架构介绍
    • SpringCloud介绍
    • Spring Cloud:生产者与消费者
    • Spring Cloud Eureka:构建可靠的服务注册与发现
    • Spring Cloud Ribbon:负载均衡
    • Spring Cloud Fegin:服务调用
    • Spring Cloud Hystrix:熔断器
    • Spring Cloud Zuul:统一网关路由
      • 1. Spring Cloud Zuul概述
      • 2. Zuul的核心:过滤器
        • 2.1. 创建过滤器类
        • 2.2. 注册过滤器
        • 2.3. 应用启动类
      • 3. Zuul的网关使用示例
        • 3.1创建Zuul模块
        • 3.2配置application
        • 3.3启动服务
        • 3.4调用测试
      • 4.结语:Zuul的未来和替代方案
    • Spring Cloud Config:配置中心
  • Java后端框架

    • LangChain4j

      • 介绍
      • 快速开始
      • Chat and Language Models
      • Chat Memory
      • Model Parameters
      • Response Streaming
      • AI Services
      • Agent
      • Tools (Function Calling)
      • RAG
      • Structured Outputs
      • Classification
      • Embedding (Vector) Stores
      • Image Models
      • Quarkus Integration
      • Spring Boot Integration
      • Kotlin Support
      • Logging
      • Observability
      • Testing and Evaluation
      • Model Context Protocol
  • 八股文

    • 操作系统
    • JVM介绍
    • Java多线程
    • Java集合框架
    • Java反射
    • JavaIO
    • Mybatis介绍
    • Spring介绍
    • SpringBoot介绍
    • Mysql
    • Redis
    • 数据结构
    • 云计算
    • 设计模式
    • 计算机网络
    • 锁核心类AQS
    • Nginx
  • 前端技术

    • 初识Vue3
    • Vue3数据双向绑定
    • Vue3生命周期
    • Vue-Router 组件
    • Pinia 集中式状态存储
  • 中间件

    • RocketMQ
  • 开发知识

    • 请求参数注解
    • 时间复杂度和空间复杂度
    • JSON序列化与反序列化
    • Timestamp vs Datetime
    • Java开发中必备能力单元测试
    • 正向代理和反向代理
    • 什么是VPN
    • 正则表达式
  • Java
  • SpringCloud
xiaoyang
2024-07-03
目录

Spring Cloud Zuul:统一网关路由

# 08.Spring Cloud Zuul:统一网关路由

到目前为止我们仅通过9000端口调用后端服务,那么如果我们有大量的服务岂不是需要有很多端口,但是真实的业务场景并不是这样而是通过一种网关服务。使用网关服务是一种更有效的解决方案,API网关作为核心组件之一,承担着请求路由、负载均衡、安全认证等重要功能。Spring Cloud Zuul作为一款功能强大的API网关解决方案,得到了广泛应用。本文将深入探讨Spring Cloud Zuul的各项功能,从基础配置到工作原理,再到多层负载和应用优化,全面解析其在实际应用中的最佳实践与实用技巧,为开发者提供一站式指导,助力其打造高性能、高可用的微服务架构。

# 1. Spring Cloud Zuul概述

Spring Cloud Zuul是Pivotal公司将Netflix公司的Zuul方案整合到Spring Cloud体系中的第一代网关组件。它在动态路由、监控、弹性、服务治理以及安全方面起着举足轻重的作用,是一个面向服务治理、服务编排的组件。根据Netflix的官方描述:

Zuul is the front door for all requests from devices and web sites to the backend of the Netflix streaming application. As an edge service application, Zuul is built to enable dynamic routing, monitoring, resiliency and security. It also has the ability to route requests to multiple Amazon Auto Scaling Groups as appropriate.

Zuul是所有来自设备和网站到Netflix流媒体应用后端的请求的前门。作为一个边缘服务应用,Zuul旨在实现动态路由、监控、弹性和安全。它还能够根据需要将请求路由到多个Amazon Auto Scaling组。

Zuul具备以下主要功能:

  1. 动态路由:根据配置或动态规则,将请求路由到不同的服务。
  2. 请求过滤:在请求处理的各个阶段(如前置过滤、路由过滤和后置过滤)进行过滤和修改。
  3. 负载均衡:与Ribbon等负载均衡器结合,实现请求的负载均衡。
  4. 服务降级:当服务不可用或响应缓慢时,提供降级服务。
  5. 认证和鉴权:识别每个资源的验证要求,并拒绝那些与要求不符的请求。。
  6. 其他逻辑与业务处理:可以通过自定义Filter实现各种业务逻辑。

# 2. Zuul的核心:过滤器

说到Zuul,不能不提它的核心——过滤器。Zuul的过滤器是实现灵活路由、安全等功能的基石。过滤器可以执行多种任务,如修改请求头和响应头、记录请求日志、校验请求参数等。

Zuul的工作流程可以分为四个阶段:PRE(前置过滤器)、ROUTING(路由过滤器)、POST(后置过滤器)和ERROR(错误过滤器)。每个请求在通过Zuul时,都会依次经过这些过滤器。

  1. PRE过滤器:
    • 功能:在路由请求之前执行,主要用于安全校验、日志记录、请求参数校验等。
    • 示例:验证用户身份、记录请求日志、添加通用请求头。
  2. ROUTING过滤器:
    • 功能:决定请求的路由路径,将请求转发到对应的微服务。
    • 示例:根据请求URL或参数选择合适的服务实例进行路由。
  3. POST过滤器:
    • 功能:在请求被路由到具体服务后执行,主要用于处理响应。
    • 示例:添加响应头、收集统计信息、处理响应结果。
  4. ERROR过滤器:
    • 功能:处理请求流程中发生的异常,提供统一的错误处理机制。
    • 示例:记录错误日志、返回自定义错误响应。

在微服务架构中,通常会有一个认证服务负责用户的登录与权限分配,Zuul可以作为所有请求的入口,拦截请求并校验请求是否携带了有效的身份认证信息,比如JWT(Json Web Token)。我们可以通过自定义一个Zuul前置过滤器来实现身份验证和授权。以下是一个简单的示例,展示如何实现一个PRE类型的过滤器来检查请求头中的JWT(Json Web Token)。

image-20240704110851408

# 2.1. 创建过滤器类

首先,创建一个自定义过滤器类,继承ZuulFilter类,并实现相应的方法:

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import javax.servlet.http.HttpServletRequest;

public class AuthPreFilter extends ZuulFilter {

    @Override
    public String filterType() {
        return "pre"; // 表示这是一个前置过滤器
    }

    @Override
    public int filterOrder() {
        return 1; // 过滤器执行顺序,越小优先级越高
    }

    @Override
    public boolean shouldFilter() {
        return true; // 是否执行该过滤器
    }

    @Override
    public Object run() throws ZuulException {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();

        String authHeader = request.getHeader("Authorization");

        if (authHeader == null || !authHeader.startsWith("Bearer ")) {
            ctx.setSendZuulResponse(false); // 拒绝请求
            ctx.setResponseStatusCode(401); // 设置响应状态码为401
            ctx.setResponseBody("Authorization token is missing or invalid");
            return null;
        }

        // 这里可以添加进一步的JWT校验逻辑,例如解析和验证JWT
        String token = authHeader.substring(7);
        try {
            // 验证JWT
            // 如果验证失败,可以抛出异常或者设置响应状态码
        } catch (Exception e) {
            ctx.setSendZuulResponse(false);
            ctx.setResponseStatusCode(401);
            ctx.setResponseBody("Invalid token");
            return null;
        }

        return null;
    }
}
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

# 2.2. 注册过滤器

将自定义过滤器注册为Spring Bean,以便Zuul能够使用它:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ZuulConfig {

    @Bean
    public AuthPreFilter authPreFilter() {
        return new AuthPreFilter();
    }
}
1
2
3
4
5
6
7
8
9
10
11

# 2.3. 应用启动类

确保你的应用启动类已经启用了Zuul代理和Eureka客户端:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

@SpringBootApplication
@EnableZuulProxy
@EnableEurekaClient
public class ZuulApplication {
    public static void main(String[] args) {
        SpringApplication.run(ZuulApplication.class, args);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13

通过自定义一个前置过滤器,我们可以在请求进入Zuul网关时进行身份验证和授权。这个示例展示了如何检查JWT令牌,并根据验证结果决定是否转发请求到后端服务。通过这种方式,我们可以在微服务架构中增强系统的安全性。

# 3. Zuul的网关使用示例

# 3.1创建Zuul模块

导入zuul依赖和eureka-client依赖,至于为什么导入eureka-client模块,因为Zuul需要从Eureka服务注册中心获取微服务实例的信息,从而实现动态路由和负载均衡。Zuul通过集成Spring Cloud的其他组件,如Eureka、Ribbon和Hystrix,提供了动态路由、负载均衡和熔断等高级功能。

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <artifactId>cloud-zuul-80</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>cloud-zuul-80</name>
    <description>cloud-zuul-80</description>
    <parent>
        <groupId>cn.ywenrou</groupId>
        <artifactId>spring-cloud-demo</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <dependencies>
        <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>
    </dependencies>
    
</project>
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

# 3.2配置application

server:
  port: 80

#spring 配置
spring:
  application:
    name: cloud-zuul-80
#eureka配置
eureka:
  client:
    #表示是否将自己注册进eureka  默认为true
    register-with-eureka: true
    #是否从EurekaServer中抓取已有的注册信息,默认为true,单点无所谓,集群必须设置true才能和ribbon使用负载均衡
    fetch-registry: true
    service-url:
      #单机配置
      defaultZone: http://localhost:7001/eureka
zuul:
  routes:
    user-service:
      path: /service2/**
      service-id: cloud-service2
    order-service:
      path: /service1/**
      service-id: cloud-service1
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

# 3.3启动服务

package cn.ywenrou;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

@EnableEurekaClient
@EnableZuulProxy // 启用Zuul代理
@SpringBootApplication
public class CloudZuul80Application {

    public static void main(String[] args) {
        SpringApplication.run(CloudZuul80Application.class, args);
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 3.4调用测试

可以发现无需在通过端口调用服务,可以使用Postman或者浏览器访问http://localhost:80/service1/,这个请求应该会被转发到service1服务。同样,访问http://localhost:80/service/,请求会被转发到service2服务。

# 4.结语:Zuul的未来和替代方案

随着微服务架构的日益普及,服务网关在系统中扮演着越来越重要的角色。Zuul作为Netflix OSS套件的一部分,一直是微服务网关的佼佼者,提供了路由、过滤、监控等强大功能。但随着技术的发展,Zuul本身也在不断进化,同时也有新的技术和工具出现,为微服务架构提供更多的选择。

Zuul 2的新特性

Zuul 1.x虽然功能强大,但它是基于阻塞I/O操作的,这在处理大量并发请求时可能成为瓶颈。Netflix意识到了这个问题,并推出了Zuul 2。Zuul 2完全重写了Zuul的核心,采用了异步非阻塞I/O的架构,大大提高了性能和可伸缩性。此外,Zuul 2还引入了更多新特性和改进,比如更灵活的路由规则、动态加载和卸载过滤器等,使得它更加强大和易用。

Spring Cloud Gateway作为替代方案

随着Spring Cloud生态系统的不断发展,Spring Cloud Gateway应运而生,它是专为微服务架构设计的一个新一代API网关。与Zuul 1.x相比,Spring Cloud Gateway基于异步非阻塞模型,能更好地处理高并发场景。它利用了Spring Framework 5、Spring Boot 2和Project Reactor等现代技术,提供了路由、过滤、限流等功能,并且与Spring生态系统的集成更加紧密。

Spring Cloud Gateway支持动态路由配置、熔断、负载均衡等功能,而且配置方式更加灵活,可以使用Java代码、配置文件甚至是动态配置源(如Consul、Nacos)来配置路由规则和过滤器。这使得Spring Cloud Gateway成为构建现代微服务架构的强有力的选择。

编辑 (opens new window)
上次更新: 2025/04/01, 01:48:12

← Spring Cloud Hystrix:熔断器 Spring Cloud Config:配置中心→

最近更新
01
操作系统
03-18
02
Nginx
03-17
03
后端服务端主动推送消息的常见方式
03-11
更多文章>
Theme by Vdoing | Copyright © 2023-2025 xiaoyang | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式