深入理解 API 网关:原理、功能和用途

本文最后更新于:6 个月前

前言

  • 这篇博客将会介绍什么是网关、为什么要使用网关以及如何使用网关等相关知识
  • 在日益数字化和互联互通的时代,网关(Gateway)已经成为网络架构中不可或缺的一环。无论是企业网络还是个人用户,使用网关都能带来众多的好处和优势。

🔥 推荐阅读:

为什么要使用网关

  • 为什么要使用网关呢?
  • 首先,网关能够提供强大的网络安全保护。当今的网络环境充满了各种威胁和攻击,如病毒、恶意软件、黑客入侵等等。网关作为网络的前沿守卫,能够监控、过滤和阻止来自外部网络的恶意流量,确保内部网络的安全。它能够识别和阻止潜在的风险,保护机密数据和敏感信息免受损失。
  • 其次,网关能够管理和优化网络流量。在庞大的网络环境中,流量管理和控制变得至关重要。网关可以实施流量限制、负载均衡和优先级管理等策略,确保网络资源的合理利用和高效分配。它能够减轻网络拥塞、提高网络性能,提供更优质的网络体验。
  • 此外,网关还可以连接不同类型的网络。无论是公共云服务提供商、私有网络还是远程办公场景,网关都能搭建起桥梁连接不同的网络环境。通过网关的中转,用户可以访问不同网络中的资源和服务,实现远程访问和协作。
  • 总而言之,无论是保护网络安全管理网络流量,还是连接不同网络环境,网关都发挥着至关重要的作用。通过使用网关,我们能够打造更安全、高效和灵活的网络架构,满足各种实际需求。
  • 希望这个简单的介绍能帮助你理解为什么需要使用网关,以及在何种情景下使用。如有任何疑问,请随时向我提问。祝你写作顺利!

正文

网关的分类

  • 我们之前学习过 Nginx,它以其优秀的负载均衡和反向代理功能而闻名,这两个特点恰巧也赋予了 Nginx 作为网关的能力
  • 有关 Nginx的相关知识,可以在《》一文中学习了解

  • 我们可以按照是否与具体的业务逻辑相绑定,对网关的类别进行划分:

  • 网关的分类:
    • 全局网关(接入层网关): 作用是负载均衡、请求日志等,不和业务逻辑绑定
    • 业务网关(微服务网关): 存在一些业务逻辑,作用是将请求转发到不同的业务/项目/接口/服务
  • 参考文章:https://blog.csdn.net/qq_21040559/article/details/122961395

实现网关

Spring Cloud Gateway

核心概念

  • 路由:根据什么条件,转发到哪里去
  • 断言:定制一套规则、条件, 用来确定如何转发路由
  • 过滤器: 对请求进行一系列的处理, 比如添加请求头、添加请求参数

请求流程:

  1. 客户端发起请求
  2. Handler Mapping: 根据断言,将请求转发到对应的路由
  3. Web Handler: 处理请求(一层层经过过滤器)
  4. 实际调用服务

两种配置方式

  1. 编程式(灵活、相对麻烦)
  2. 配置式(方便、规范)
    • 简化版

    • 全称版

快速测试

  • 在IDEA中新建工程,导入以下依赖,如图所示:
1
2
3
4
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-Gateway</artifactId>
</dependency>
1
2
3
4
5
6
 
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
1
2
3
4
5
6
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>

image-20230818103912848

image-20230818103909751

  • 编程式,编写Gateway配置信息:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* @author 邓哈哈
* 2023/8/18 11:41
* Function:
* Version 1.0
*/

@Configuration
public class GatewayConfig {
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("blog", r -> r.path("/blog/**")
.uri("https://deng-2022.gitee.io/blog/"))
.route("baidu", r -> r.host("/baidu/**")
.uri("https://www.baidu.com"))
.build();
}
}
  • 配置式,编写Gateway配置信息:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
spring:
cloud:
Gateway:
routes:
- id: memory-api
uri: http://localhost:8000/user/login
predicates:
- Path=/api/**
- id: baidu
uri: https://www.baidu.com
predicates:
- Path=/baidu/**
- id: blog
uri: https://deng-2022.gitee.io/blog/
predicates:
- Path=/blog/**
  • 这两种配置作用是一样的,转发路由
1
2
server:
port: 8090

image-20230818133658686

网关的作用

  • 网关的作用包括:
  1. 路由
  2. 负载均衡
  3. 统一鉴权
  4. 跨域
  5. 统一业务处理(缓存)
  6. 访问控制
  7. 发布控制
  8. 流量染色
  9. 接口保护
    1. 限制请求
    2. 信息脱敏
    3. 降级(熔断)
    4. 限流:学习令牌桶算法、学习漏桶算法,学习一下 RedisLimitHandler
    5. 超时时间
  10. 统一日志
  11. 统一文档

路由

  • 起到转发的作用
  • 比如有接口 A 和接口 B, 网关会记录这些信息,根据用户访问的地址和参数,转发请求到对应的接口(服务器/集群)
    • /a => 接口 A
  • /b => 接口 B

负载均衡

  • 在路由的基础上
  • /c => 服务 A / 集群 A (随机转发到其中的某一个机器)
  • uri 从固定地址改成 lb:xxxx

统一处理跨域

  • 网关统一处理跨域,不用在每个项目里单独处理

发布控制

  • 灰度发布,比如上线新接口,先给新接口分配 20% 的流量,老接口 80%, 再慢慢调整比例

流量染色

  • 给请求(流量)添加一些标识,一般是设置请求头中,添加新的请求头

统一接口保护

  1. 限制请求:https://docs.spring.io/spring-cloud-Gateway/docs/current/reference/html/#requestheadersize-Gatewayfilter-factory
  2. 信息脱敏:https://docs.spring.io/spring-cloud-Gateway/docs/current/reference/html/#the-removerequestheader-Gatewayfilter-factory
  3. 降级(熔断):https://docs.spring.io/spring-cloud-Gateway/docs/current/reference/html/#fallback-headers
  4. 限流:https://docs.spring.io/spring-cloud-Gateway/docs/current/reference/html/#the-requestratelimiter-Gatewayfilter-factory
  5. 超时时间:https://docs.spring.io/spring-cloud-Gateway/docs/current/reference/html/#http-timeouts-configuration
  6. 重试(业务保护):https://docs.spring.io/spring-cloud-Gateway/docs/current/reference/html/#the-retry-Gatewayfilter-factory

统一业务处理

  • 把每个项目中都要做的通用逻辑放到上层(网关),统一处理,比如本项目的次数统计

统一鉴权

  • 判断用户是否有权限进行操作,无论访问什么接口,都统一验证权限,避免重复写验证权限操作。

访问控制

  • 黑白名单,比如限制 DDOS IP

统一日志

  • 统一的请求、响应信息记录

统一文档

  • 将下游项目的文档进行聚合,在一个页面统一查看

开启日志

1
2
3
4
5
6
logging:
level:
org:
springframework:
cloud:
Gateway: trace

常用配置

断言

  • After 在 xx 时间之后
1
2
3
4
5
6
7
8
spring:
cloud:
Gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- After=2017-01-20T17:42:47.789-07:00[America/Denver]
  • Before 在 xx 时间之前
1
2
3
4
5
6
7
8
9
spring:
cloud:
Gateway:
routes:
- id: before_route
uri: https://example.org
predicates:
- Before=2017-01-20T17:42:47.789-07:00[America/Denver]

  • Between 在 xx 时间之间
1
2
3
4
5
6
7
8
9
spring:
cloud:
Gateway:
routes:
- id: between_route
uri: https://example.org
predicates:
- Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]

  • 请求类别
1
2
3
4
5
6
7
8
9
spring:
cloud:
Gateway:
routes:
- id: method_route
uri: https://example.org
predicates:
- Method=GET,POST

  • 请求头(包含 cookie)
1
2
3
4
5
6
7
8
9
spring:
cloud:
Gateway:
routes:
- id: header_route
uri: https://example.org
predicates:
- Header=X-Request-Id, \d+

1
2
3
4
5
6
7
8
spring:
cloud:
Gateway:
routes:
- id: cookie_route
uri: https://example.org
predicates:
- Cookie=chocolate, ch.p
  • 路由转发
1
2
3
4
5
6
7
8
9
spring:
cloud:
Gateway:
routes:
- id: path_route
uri: https://example.org
predicates:
- Path=/red/{segment},/blue/{segment}

  • 查询参数
1
2
3
4
5
6
7
8
9
spring:
cloud:
Gateway:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=green

  • 客户端地址
1
2
3
4
5
6
7
8
9
spring:
cloud:
Gateway:
routes:
- id: remoteaddr_route
uri: https://example.org
predicates:
- RemoteAddr=192.168.1.1/24

  • 权重
1
2
3
4
5
6
7
8
9
10
11
12
spring:
cloud:
Gateway:
routes:
- id: weight_high
uri: https://weighthigh.org
predicates:
- Weight=group1, 8
- id: weight_low
uri: https://weightlow.org
predicates:
- Weight=group1, 2

过滤器

  • 基本功能:对请求头、请求参数、响应头的增删改查
  1. 添加请求头
  2. 添加请求参数
  3. 添加响应头
  4. 降级
  5. 限流
  6. 重试
  • 这里就不引入具体配置了,详细配置可在官网文档查看:
  • Spring Cloud Gateway
  • 引入:
1
2
3
4
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-circuitbreaker-reactor-resilience4j</artifactId>
</dependency>

总结


深入理解 API 网关:原理、功能和用途
http://example.com/2023/08/17/深入理解 API 网关:原理、功能和用途/
作者
Memory
发布于
2023年8月17日
更新于
2023年11月18日
许可协议