程序员scholar 程序员scholar
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • Vue3 + TS
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • Vue3 + TS
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
npm

(进入注册为作者充电)

  • 微服务基础

    • 了解SpringCloud微服务架构
    • 启动多个微服务项目
    • Eureka 服务注册
    • Ribbon 负载均衡
    • Nacos 下载与安装
    • Nacos 服务注册
    • Nacos 配置管理
    • openFeign 远程调用
    • OpenFeign 最佳实践
    • Gateway 网关
      • 1. 什么是 SpringCloud Gateway
        • 其他网关组件对比
        • SpringCloud Gateway 功能特征
      • 2. 为什么需要 SpringCloud Gateway
        • 问题分析
        • 网关的作用
        • 核心功能特性
        • Gateway 的架构图
        • Gateway 的主要功能
      • 3. Gateway 快速开始
        • 1. 创建 Gateway 微服务
        • 2. 引入必要的依赖
        • 3. 编写启动类
        • 4. 配置路由规则
        • 5. 测试 Gateway 服务
      • 4. Gateway 路由流程图
      • 5. Gateway 使用小结
    • Gateway 进阶使用
    • Sentinel 服务保护
    • Sentinel 整合 Feign
    • 分布式事务 Seata
    • 什么是分布式
    • 什么是RPC框架
  • 微服务之DDD架构思想

  • 微服务
  • 微服务基础
scholar
2024-08-24
目录

Gateway 网关

# Gateway 网关

# 1. 什么是 SpringCloud Gateway

网关作为流量的入口,常见功能包括路由转发、权限校验、限流等。SpringCloud Gateway 是 Spring Cloud 官方推出的第二代网关框架,旨在取代 Netflix Zuul。相较于 Zuul,SpringCloud Gateway 提供了更优越的性能和更强大的功能。

SpringCloud Gateway 的特点:

  • 基于 WebFlux、Netty 和 Reactor,实现了响应式的 API 网关。
  • 提供了动态路由、路径重写、服务发现、流控降级等功能。
  • 使用 Predicate(断言)和 Filter(过滤器)进行灵活的路由配置和处理。

SpringCloud Gateway 结构图

# 其他网关组件对比

在 SpringCloud 微服务体系中,Zuul 是传统网关的代表,但在 2.x 版本中,Zuul 升级缓慢,SpringCloud 自主研发了 SpringCloud Gateway 来替代 Zuul。

需要注意的是,很多文章提到 Zuul 是阻塞的,而 Gateway 是非阻塞的,这并不完全准确。Zuul 1.x 版本是阻塞的,但在 2.x 版本中,Zuul 也基于 Netty,具备非阻塞能力。两者在性能上的差异并没有明显的区别。

# SpringCloud Gateway 功能特征

  1. 基于 Spring Framework 5、Project Reactor 和 Spring Boot 2.0 构建。
  2. 支持动态路由:匹配任意请求属性。
  3. 支持路径重写。
  4. 集成服务发现功能(如 Nacos、Eureka)。
  5. 支持流控降级功能(如 Sentinel、Hystrix)。
  6. 提供丰富的 Predicate 和 Filter 功能,实现复杂的请求处理逻辑。

# 2. 为什么需要 SpringCloud Gateway

在微服务架构中,系统被拆分为多个微服务,客户端如何调用这些服务呢?如果没有网关,客户端必须记录每个微服务的地址并分别调用。

# 问题分析

这种架构存在以下问题:

  1. 每个业务都需要实现 鉴权、限流、权限校验、跨域 等逻辑,如果各自为战,重复开发工作量大且不易维护。
  2. 随着业务复杂度增加,多个微服务协同工作时,客户端需要维护多个域名,难以管理。同时,连接数瓶颈问题会显现,尤其是在移动端下效率低下。
  3. 如果微服务进行重构,例如将一个服务拆分为多个服务,客户端也需要进行配套改造,增加了系统维护的复杂度。

# 网关的作用

上述问题可以通过网关来解决。网关提供了以下核心功能:

  1. 权限控制:校验用户是否有访问权限,如果没有则进行拦截。
  2. 路由和负载均衡:网关根据规则将请求转发到对应的微服务,支持负载均衡。
  3. 限流:根据下游服务的处理能力,限制请求流量,避免服务崩溃。

# 核心功能特性

稳定性:

  • 全局流控、日志统计
  • 防止 SQL 注入、Web 攻击
  • 黑白名单管理
  • 证书、加解密处理

服务级别流控:

  • 服务降级与熔断
  • 路由与负载均衡、灰度发布
  • 服务过滤、权限验证
  • 参数校验、多级缓存策略

# Gateway 的架构图

SpringCloud Gateway 架构图

# Gateway 的主要功能

  • 权限控制:校验请求的合法性,确保只有有权限的请求才可以访问后端服务。
  • 路由和负载均衡:将请求根据路径、请求头等信息路由到相应的服务,支持负载均衡。
  • 限流:在高并发场景下,按需控制请求速率,保护后端服务稳定性。

SpringCloud Gateway 是微服务架构中重要的组成部分,通过它,我们可以实现统一的流量管理、服务发现、限流、权限校验等功能。

# 3. Gateway 快速开始

下面我们通过一个简单示例演示 SpringCloud Gateway 的基本路由功能。我们将基于之前搭建的用户服务(UserService)和订单服务(OrderService)进行测试。

# 1. 创建 Gateway 微服务

首先,我们创建一个新的 Spring Boot 项目,命名为 gateway。

创建微服务

# 2. 引入必要的依赖

在 pom.xml 文件中引入 Gateway 和 Nacos 服务发现的依赖:

<!-- Spring Cloud Gateway 依赖 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- Nacos 服务发现依赖 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
1
2
3
4
5
6
7
8
9
10

说明:Gateway 依赖提供了网关功能,Nacos 依赖用于服务发现,实现通过服务名称进行负载均衡。

# 3. 编写启动类

在 src/main/java 目录下编写启动类 GateWayApplication:

package com.example.gateway;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.core.env.Environment;
import org.springframework.context.ConfigurableApplicationContext;

/**
 * 网关服务启动类
 */
@SpringBootApplication
public class GateWayApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(GateWayApplication.class, args);
        Environment environment = context.getBean(Environment.class);

        System.out.println("访问链接:http://localhost:" + environment.getProperty("server.port"));
        System.out.println("(♥◠‿◠)ノ゙  项目启动成功   ლ(´ڡ`ლ)゙  \n" +
                " .-------.       ____     __        \n" +
                " |  _ _   \\      \\   \\   /  /    \n" +
                " | ( ' )  |       \\  _. /  '       \n" +
                " |(_ o _) /        _( )_ .'         \n" +
                " | (_,_).' __  ___(_ o _)'          \n" +
                " |  |\\ \\  |  ||   |(_,_)'         \n" +
                " |  | \\ `'   /|   `-'  /           \n" +
                " |  |  \\    /  \\      /           \n" +
                " ''-'   `'-'    `-..-'              ");
    }
}
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

说明:该启动类为网关服务的入口,Spring Boot 启动时会加载相关配置并启动网关服务。

# 4. 配置路由规则

在 SpringCloud Gateway 中,路由是最核心的配置部分。它决定了请求如何被转发到具体的微服务。我们通过在 src/main/resources/application.yml 文件中定义路由规则来实现这一点。

server:
  port: 10010 # 网关服务的端口,用户将通过该端口访问网关

spring:
  application:
    name: gateway # 网关服务的名称
  cloud:
    nacos:
      server-addr: localhost:8848 # Nacos 服务注册中心的地址
    gateway:
      routes: # 路由配置列表
        - id: userservice # 路由 ID,必须唯一,可自定义命名
          uri: lb://userservice # 目标服务地址,lb 代表负载均衡,后跟服务名称
          predicates: # 路由断言规则,用于判断请求是否匹配路由
            - Path=/user/** # 匹配路径以 /user/ 开头的所有请求
          filters: # 路由过滤器,用于在请求和响应之间进行额外处理
            - AddRequestHeader=Truth, scholar is freaking awesome! # 添加自定义请求头
        - id: orderservice # 另一个路由的 ID,必须唯一
          uri: lb://orderservice # 目标服务地址,服务名称为 orderservice
          predicates: # 路由断言规则
            - Path=/order/** # 匹配路径以 /order/ 开头的所有请求
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

配置项详细说明:

  1. server.port(必须配置):

    • 网关服务的端口,所有客户端请求将通过此端口访问网关。
    • 例如:port: 10010 表示网关服务运行在 10010 端口。
  2. spring.application.name(必须配置):

    • 网关服务的名称,用于服务注册和识别。
    • 例如:name: gateway 是网关服务的名称。
  3. spring.cloud.nacos.server-addr(必须配置):

    • Nacos 服务注册中心的地址,用于服务发现和注册。
    • 例如:server-addr: localhost:8848。
  4. spring.cloud.gateway.routes(必须配置):

    • 网关的路由配置列表,每个路由定义一个转发规则。

    • 路由配置包括以下部分:

    • id(必须配置,且唯一):

      • 路由的唯一标识符,可自定义命名,建议使用有意义的名称,如 userservice、orderservice 等。
      • 例如:id: userservice。
    • uri(必须配置):

      • 目标服务的地址,支持两种形式:
        • http://:用于固定地址的转发,例如 http://127.0.0.1:8081。
        • lb://:用于负载均衡,后跟服务名称,例如 lb://userservice。这表示通过服务名进行动态负载均衡转发。
    • predicates(必须配置):

      • 路由断言规则,用于匹配请求是否符合条件。常见的断言包括路径、请求头、请求参数等。
      • 例如:- Path=/user/** 表示匹配路径以 /user/ 开头的所有请求。
    • filters(可选配置):

      • 路由过滤器,用于在请求和响应之间进行处理。常见的过滤器功能包括添加请求头、修改请求参数、响应处理等。
      • 例如:- AddRequestHeader=Truth, scholar is freaking awesome! 添加一个名为 Truth 的请求头,值为 scholar is freaking awesome!。

路由规则配置的灵活性

  • 路由的 id 可以自定义命名,只要保证唯一即可,建议使用能清晰描述目标服务的名称。
  • uri 可根据需求选择固定地址或服务名称,通过 lb:// 来支持负载均衡。
  • predicates 中的路径匹配规则可根据业务需求灵活配置,例如按路径、请求头、参数等进行匹配。
  • filters 是可选项,可以根据需求自定义处理逻辑。

# 5. 测试 Gateway 服务

启动网关服务后,我们访问的是网关的服务端口,而不是具体服务的端口。比如:

在浏览器中访问 http://localhost:10010/user/1,注意这里 10010 是网关的端口。根据我们在 application.yml 中的配置,符合路径 /user/** 的请求会被网关转发到 userservice 服务。

这意味着,虽然我们访问的是网关的地址,但实际请求会被转发到对应的用户服务(userservice),并返回用户服务的响应结果:

测试结果

网关作为统一入口,屏蔽了具体服务的内部实现,客户端只需要与网关交互即可。

# 4. Gateway 路由流程图

为了更清晰理解网关的工作原理,下面是 Gateway 路由的流程图:

Gateway 路由流程图

# 5. Gateway 使用小结

网关的搭建流程如下:

  1. 创建项目并引入 Gateway 和 Nacos 服务发现依赖。
  2. 配置 application.yml 文件,包括服务信息、Nacos 地址和路由规则。
  3. 通过路由 ID、URI、断言和过滤器配置,实现请求的路由和处理。

路由配置的关键部分:

  • 路由 ID:路由的唯一标识。
  • URI:路由的目标地址,http 表示固定地址,lb 表示基于服务名的负载均衡。
  • 断言(Predicates):判断请求是否匹配路由规则,如按路径匹配。
  • 过滤器(Filters):对请求或响应进行处理,如添加请求头信息。

公众号封面

编辑此页 (opens new window)
上次更新: 2024/12/28, 18:32:08
OpenFeign 最佳实践
Gateway 进阶使用

← OpenFeign 最佳实践 Gateway 进阶使用→

Theme by Vdoing | Copyright © 2019-2025 程序员scholar
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式