SpringCloud核心组件(五)

Gateway

官网

一. 概述简介

1. Gateway 是什么

Spring Cloud Gateway是 Spring 官方基于 Spring Boot 2.x、Spring WebFlux 和 Project Reactor 构建的网关Spring Cloud Gateway旨在为微服务架构提供一种简单而有效的统一的 API路由管理方式。Spring Cloud Gateway 作为 Spring Cloud 生态系中的网关,目标是替代 ZUUL,其不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控/埋点,和限流等。

2. 什么是网关?

网关(Gateway)又称网间连接器,网关在网络层实现服务之间网络互连。用程序的话来说就是请求转发。他就好比小区的门一样,你想进来小区,必须通过门才能进来。为什么要有这个门?为了方便管理以及安全考虑,就好比现在疫情期间,动不动小区封了,假如小区没有门,想要封小区还得费特别大的劲将小区给围住。

再回到程序当中,现在非常流行微服务系统,将整体应用拆分为了多个模块,那么问题来了,前端页面肯定会涉及到调用不同微服务的接口,一个微服务就代表着一个端口的应用,每个微服务都是独立的,那么前端在调用的时候不可能将访问地址设置成多个呀。设置成多个当然也可以,弊端就是开发过程当中我们涉及到环境(域名服务器 ip)的切换,那还得改多个,因此网关为解决这个问题而生,网关可以将多个微服务访问的地址进行聚拢起来,你要访问哪个微服务的接口,直接访问网关,网关负责给你转发到对应的微服务地址上,因此前端只需要知道网关的地址服务地址就可以了。

3.Gateway 和 Nginx 两个网关的区别

在学习 Gateway 网关的时候很容易联想到 Nginx,甚至刚接触的时候会好奇很多架构图上面 画的两个网关竟然都用到了,那么他们两个到底有什么关联性?

下图当中圈出来的就是 Gateway 所在的位置。而 Nginx 属于在 Gateway 上层。甚至可以在外部请求的上层,因为 Nginx 可以用来做网关层的负载均衡,同时他还可以用来做流量入口。因为他本身就是服务器,实际开发当中都是通过 Nginx 来做流量入口的。

什么是流量入口?

流量入口的意思就是假如我有个 html 放到 linux 当中,那么外面的人怎么才能访问到 linux 当中的页面呢?Nginx 可以用来解决这个问题,他本身就是一个服务器,使用过程就是开启端口然后监听请求,当请求来了,可以将请求 指向本机的任意可访问的html文件

20241115191142

Gateway 可以称之为微服务网关(业务网关),而 Nginx 可以作为整个应用的流量网关,以及微服务网关的负载均衡。业务网关针对具体的业务需要提供特定的流控策略、缓存策略、鉴权认证策略等等。流量网关通常只专注于全局的 Api 管理策略,比如全局流量监控、日志记录、全局限流、黑白名单控制、接入请求到业务系统的负载均衡等,有点类似防火墙。Kong 就是典型的流量网关。

  1. nginx 是用 C 语言写的,自定义扩展的话,要么写 C 要么写 lua
  2. gateway 是 java 语言的一个框架,可以在框架上进行代码的扩展与控制,例如:安全控制,统一异常处理,XXS,SQL 注入等;权限控制,黑白名单,性能监控,日志打印等;

4.Gateway 能干嘛

  • 反向代理
  • 鉴权
  • 限流
  • 熔断
  • 日志监控

5.gateway 三大核心概念

  • Route(路由):路由是构建网关的基本模块,它由 ID,目标 URI,一系列的断言和过滤器组成,如果断言为 true 则匹配该路由。
  • Predicate(断言):参考的是 Java8 的 java.util.function.Predicate,开发人员可以匹配 HTTP 请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由。
  • Filter(过滤):指的是 Spring 框架中 GatewayFilter 的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改。

web 请求,通过一些匹配条件,定位到真正的服务节点。并在这个转发过程的前后,进行一些精细化控制。

predicate 就是我们的匹配条件;
而 filter,就可以理解为一个无所不能的拦截器,可以在执行前后来执行自己的逻辑,有了这两个元素,再加上目标 uri,就可以实现一个具体的路由了

6.运行方式

20241115191354

客户端向 Spring Cloud Gateway 发出请求。然后在 Gateway Handler Mapping 中找到与请求相匹配的路由,将其发送到 Gateway Web Handler

Handler 再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回。
过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前(“pre”)或之后(“post”)执行业务逻辑。

Filter 在“pre”类型的过滤器可以做参数校验、权限校验、流量监控、日志输出、协议转换等,在“post”类型的过滤器中可以做响应内容、响应头的修改,日志的输出,流量监控等有着非常重要的作用。

核心逻辑: 路由转发+执行过滤器链

二. 入门案例

假如我有个 8080 端口的服务,然后他有两个接口 8080 和 9527,但是我又不想让别人通过 8080 端口访问,我想让他通过 9527 访问怎么办?很简单通过 Gateway 搭建一个网关服务即可解决该问题。

  1. 创建 SpringBoot 工程 gateway,引入网关依赖
  2. 编写启动类
  3. 编写基础配置:服务端口,应用名称
  4. 编写路由规则
  5. 启动网关服务进行测试

a.创建gateway模块,在pom.xml中引入依赖

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
<?xml version="1.0" encoding="UTF-8"?>
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.nianxi</groupId>
<artifactId>springNacos_demo</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>

<artifactId>gateway</artifactId>

<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
<!--nacos服务注册发现依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--gateway依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
</dependencies>
</project>

b.创建启动类GatewayApplication

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.nianxi;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
* @author Jie.
* @description: TODO
* @date 2024/11/15
* @version: 1.0
*/
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}

c.创建配置文件配置gateway与nacos

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
server:
port: 8080
spring:
application:
name: gateway
cloud:
nacos:
discovery:
server-addr: 192.168.146.128:8848
gateway:
routes:
- id: user-service # 路由标识,必须唯一
uri: lb://userService # 路由转发地址,lb代表负载均衡
predicates: # 断言,判断请求是否满足条件
- Path=/user/** # 请求路径匹配
- id: order-service
uri: lb://orderService
predicates:
- Path=/order/**

d. 访问测试

20241115194801

三. 总结

20241115194826