文章目录
- 一、网关
 - 1.1 网关是什么
 - 1.2 API网关的作用
 
- 二、Spring Cloud Gateway
 - 2.1 简介
 - 2.2 搭建步骤
 - 2.3 路由断言工厂
 - 2.3.1 什么是路由断言工厂
 - 2.3.2 Spring Cloud Gateway提供的11 种断言工厂
 
- 2.4 网关过滤器
 - 2.4.1 介绍
 - 2.4.2 网关过滤器作用
 - 2.4.3 过滤器配置
 - 2.4.4 全局过滤器GlobalFilter
 - 2.4.5 过滤器执行顺序
 
- 2.5 跨域问题处理
 - 2.5.1 什么是跨域
 - 2.5.2 跨域问题处理
 
一、网关
1.1 网关是什么
  网关(Gateway)是指在计算机网络中,用于连接两个不同网络的网络设备或软件。它可以将来自一个网络的请求转发到另一个网络,并将响应返回给原始网络。网关通常用于将本地网络连接到互联网,或将一个局域网连接到另一个局域网。在互联网上,网关通常是用于连接企业内部网络和互联网的设备,也被称为企业网关(Enterprise Gateway)。
 
在现代的分布式系统中,网关也可以指 API 网关(API Gateway),它是用于管理和保护后端服务的服务器软件。API 网关通常充当所有请求和响应的中间层,提供路由、安全、缓存、限流等功能。它还可以将多个微服务组合成一个 API,使其对外提供统一的接口。
总的来说,网关是一种连接不同网络或系统的设备或软件,用于转发和管理数据流量,实现网络间的通信和数据交换。
1.2 API网关的作用
API 网关的主要作用:
- 路由和负载均衡:API 网关可以根据请求的 URI、请求头、请求方法等信息,将请求路由到不同的后端服务。它还可以使用负载均衡算法将请求分发到多个实例中,从而提高系统的可用性和性能。
 - 安全性:API 网关可以充当安全层,用于保护后端服务。它可以提供身份验证、授权、访问控制等安全功能。
 - 缓存:API 网关可以使用缓存来减轻后端服务的负担,并提高系统的性能。它可以将响应缓存在自己的本地缓存中,从而减少对后端服务的请求次数。
 - 监控和日志记录:API 网关可以对请求和响应进行监控和记录,并提供实时的指标和警报。这有助于了解系统的健康状况和性能,以便进行优化和调整。
 - 限流和熔断:API 网关可以使用限流和熔断机制来保护后端服务免受流量超载和故障的影响。它可以监控请求的流量并动态调整请求速率,以确保系统的可靠性和稳定性。
 
综上所述,API 网关是一种非常重要的中间层,可以帮助开发者管理和保护后端服务,并提高系统的可用性、可靠性和性能。
二、Spring Cloud Gateway
2.1 简介
  Spring Cloud Gateway 是一个基于 Spring Framework 5 和 Spring Boot 2 的 API 网关服务。它提供了一些常见的路由、过滤、限流等功能,可以帮助开发者快速地构建出高性能、高可用的 API 网关服务。它是 Spring Cloud 生态系统中的一个组件,支持多种路由规则和路由断言,可轻松地实现 API 的路由和负载均衡。
 
Spring Cloud Gateway 基于异步非阻塞的 Reactor 模型作为底层技术栈,使用 Netty 作为 HTTP 服务器,可以处理高并发的请求。它的路由规则和路由断言可以根据请求的 URI、请求头、请求方法等信息,将请求路由到不同的后端服务,并使用负载均衡算法将请求分发到多个实例中,从而提高系统的可用性和性能。
Spring Cloud Gateway 还提供了一些过滤器,用于请求和响应的处理和转换,以及实现一些常见的功能,如安全认证、限流、重试等。它可以与 Spring Cloud Config、Spring Cloud Discovery、Spring Cloud Security 等其他 Spring Cloud 组件集成使用,提供更全面的功能和更好的开发体验。
总的来说,Spring Cloud Gateway 是一款强大的 API 网关框架,可以帮助开发者构建出高性能、高可用的 API 网关服务,简化微服务架构中的网关层设计和开发。
2.2 搭建步骤
-  
在需要创建网关的项目添加一个module;
 -  
添加网关依赖、nacos服务发现依赖;
 
<!--网关-->
<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>
 
- 编写启动类
 
@SpringBootApplication
public class GatewayApplication {
    public static void main(String[] args) {
		SpringApplication.run(GatewayApplication.class,args);
    }
}
 
- 创建application.yml文件,添加路由配置
 
例:
server:
  port: 10010 # 网关端口
spring:
  application:
    name: gateway # 服务名称
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos地址
    gateway:
      routes: # 网关路由配置
        - id: user-service # 路由id,自定义,只要唯一即可
          # uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址
          uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
            - Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求
 
2.3 路由断言工厂
2.3.1 什么是路由断言工厂
路由断言工厂(Route Predicate Factory)是 Spring Cloud Gateway 中的一个概念,用于配置路由规则中的断言条件,根据请求的不同属性匹配对应的路由。
路由断言工厂包括多个不同的实现类,每个实现类可以根据不同的请求属性,如 URI、请求头、请求参数等,配置不同的断言条件,如匹配正则表达式、等于、包含等。在配置路由规则时,可以使用多个路由断言工厂实现类组合使用,构建出复杂的断言条件,实现灵活的路由转发和负载均衡。
Spring Cloud Gateway 中内置了多个常用的路由断言工厂实现类,如 Path、Host、Method、Header、Cookie 等,还支持自定义路由断言工厂实现类,可以继承 RoutePredicateFactory 抽象类,实现匹配逻辑和参数解析等方法。
使用路由断言工厂可以根据不同的请求属性,灵活地配置路由规则,实现请求的路由转发和负载均衡。比如,可以根据请求的 URI 匹配路由规则,将请求路由到不同的后端服务,或者根据请求的请求头信息匹配路由规则,实现安全认证或者请求转发等功能
2.3.2 Spring Cloud Gateway提供的11 种断言工厂
| 名称 | 说明 | 示例 | 
|---|---|---|
| After | 根据请求的时间戳判断是否在指定时间之后。 | - After=2037-01-20T17:42:47.789-07:00[America/Denver] | 
| Before | 根据请求的时间戳判断是否在指定时间之前。 | - Before=2031-04-13T15:14:47.433+08:00[Asia/Shanghai] | 
| Between | 根据请求的时间戳判断是否在指定时间段内。 | - Between=2037-01-20T17:42:47.789-07:00[America/Denver], 2037-01-21T17:42:47.789-07:00[America/Denver] | 
| Cookie | 根据请求的 Cookie 进行匹配,支持精确匹配和正则表达式匹配。 | - Cookie=chocolate, ch.p | 
| Header | 根据请求的 Header 头进行匹配,支持精确匹配和正则表达式匹配。 | - Header=X-Request-Id, \d+ | 
| Host | 根据请求的 Host 头进行匹配,支持精确匹配和模糊匹配。 | - Host=.somehost.org,.anotherhost.org | 
| Method | 根据请求的 HTTP 方法进行匹配,支持 GET、POST、PUT、DELETE 等 HTTP 方法。 | - Method=GET,POST | 
| Path | 根据请求的 URI 路径进行匹配,支持 Ant 风格的通配符表达式。 | - Path=/red/{segment},/blue/** | 
| Query | 根据请求的查询参数进行匹配,支持精确匹配和正则表达式匹配。 | - Query=name, Jack或者- Query=name | 
| RemoteAddr | 根据请求的远程地址进行匹配,支持 IPv4 和 IPv6。 | - RemoteAddr=192.168.1.1/24 | 
| Weight | 根据请求响应时间进行匹配,支持权重分配和最小值匹配。 | 
2.4 网关过滤器
2.4.1 介绍
Spring Cloud Gateway 的网关过滤器(GatewayFilter)是 Spring Cloud Gateway 提供的核心组件之一,用于实现请求的过滤、处理和转换等功能。网关过滤器可以根据请求的不同阶段,对请求进行处理和转换,包括请求前置处理、请求后置处理、请求转发等功能。
Spring Cloud Gateway 中的网关过滤器基于 Reactor 模式实现,使用 Netty 作为底层网络框架,具有高性能和低延迟的特点。网关过滤器是一个链式处理器,可以根据需求配置多个过滤器组成处理链,对请求进行处理和转换。
2.4.2 网关过滤器作用
Spring Cloud Gateway 的网关过滤器(GatewayFilter)的作用是对请求进行处理、转换和过滤。它们是 Spring Cloud Gateway 中非常重要的组件之一,可以在请求发送前或者请求返回后对请求进行处理,以实现请求的转发、重定向、限流、熔断、重试等功能。
网关过滤器是一个链式处理器,可以根据需求配置多个过滤器组成处理链,对请求进行处理和转换。网关过滤器在 Spring Cloud Gateway 中的作用包括:
- 请求转发:可以根据不同的请求路径和请求参数,将请求转发到不同的服务实例上。
 - 请求重定向:可以根据需要将请求重定向到不同的 URL 地址上,实现动态路由功能。
 - 限流和熔断:可以对请求进行限流和熔断处理,保证服务的高可用性和稳定性。
 - 请求重试:可以对请求进行重试,以保证请求的成功率和可靠性。
 - 安全认证:可以对请求进行身份验证和授权,保护服务的安全性和稳定性。
 - 请求转换:可以对请求进行数据转换和格式化,以适配不同的服务实例和系统之间的数据格式和协议。
 
2.4.3 过滤器配置
Spring Cloud Gateway提供了很多的网关过滤器实现类(具体可查看Spring Cloud Gateway),以AddRequestHeader为例:
假设我们有一个服务 A,它需要向服务 B 发送请求,但是服务 B 需要在请求头中添加一个特定的参数才能正常处理请求。我们可以通过在 Spring Cloud Gateway 中使用 AddRequestHeaderGatewayFilterFactory 过滤器,为服务 A 发送的请求添加所需的请求头参数,以保证服务 B 能够正常处理请求。
下面是一个简单的示例配置:
spring:
  cloud:
    gateway:
      routes:
        - id: serviceA
          uri: lb://serviceA 
          predicates:
            - Path=/serviceA/**
          filters:
            - AddRequestHeader=X-Request-Id, 123
 
上述配置将服务 A 的请求路径前缀为 /serviceA/**,并在发送请求时添加一个名为 X-Request-Id,值为 123 的请求头参数。
如果要对所有的路由都生效,则可以将过滤器工厂写到default下。格式如下:
spring:
  cloud:
    gateway:
      routes:
        - id: serviceA 
          uri: lb://serviceA 
          predicates: 
            - Path=/serviceA/** 
        - id: serviceB
          uri: lb://serviceB
          predicates:
            - Path=/serviceB/**
      default-filters:
        - AddRequestHeader=headerMsg,I like caterpillar!!!
 
2.4.4 全局过滤器GlobalFilter
全局过滤器(GlobalFilter)是 Spring Cloud Gateway 中的一种特殊的过滤器,它可以在请求被路由到具体的服务前或者服务返回响应后进行全局的处理。全局过滤器可以对请求和响应进行修改、记录日志、实现安全认证等全局性操作,是 Spring Cloud Gateway 的重要组成部分。
全局过滤器与普通过滤器的不同之处在于,它们不需要配置在具体的路由上,而是可以应用于所有的请求和响应。全局过滤器需要实现 Spring Cloud Gateway 的 GlobalFilter 接口,并实现其中的 filter 方法,在该方法中编写过滤器的逻辑代码。
全局过滤器在 Spring Cloud Gateway 中的作用包括:
- 请求响应记录:可以记录请求和响应的详细信息,便于后续的分析和排查问题。
 - 安全认证:可以对请求进行身份验证和授权,保护服务的安全性和稳定性。
 - 全局日志记录:可以对所有请求进行日志记录,方便后续的追踪和分析。
 - 请求响应转换:可以对请求和响应进行转换和格式化,以适应不同的业务场景和需求。
 - 请求响应加解密:可以对请求和响应进行加解密处理,保护数据的安全性和保密性。
 
Spring Cloud Gateway 提供了多种内置的全局过滤器实现类,同时也支持自定义全局过滤器实现类。全局过滤器是 Spring Cloud Gateway 中非常重要的组件之一,可以方便地实现请求和响应的全局处理和转换,以适应不同的业务场景和需求。
示例:
@Component
public class AuthorizeFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //1.获取请求参数
        ServerHttpRequest request = exchange.getRequest();
        MultiValueMap<String, String> params = request.getQueryParams();
        //2.获取参数中的authorization参数
        String auth = params.getFirst("authorization");
        //3.判断多数值是否等于admin
        if("admin".equals(auth)){
            //4.是,放行
            return chain.filter(exchange);
        }
        //5.否,拦截
        //5.1设置状态码
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        //5.2拦截请求
        return exchange.getResponse().setComplete();
    }
	//设置过滤器顺序
    @Override
    public int getOrder() {
        return -1;
    }
}
 
2.4.5 过滤器执行顺序
- 每一个过滤器都必须指定一个int类型的order值,order值越小,优先级越高,执行顺序越靠前。
 - GlobalFilter通过实现Ordered接口,或者添加@Order注解来指定order值,由我们自己指定。
 - 路由过滤器和defaultFilter的order由Spring指定,默认是按照声明顺序从1递增。
 - 当过滤器的order值一样时,会按照 defaultFilter > 路由过滤器 > GlobalFilter的顺序执行。
 
2.5 跨域问题处理
2.5.1 什么是跨域
  跨域指的是在 Web 应用程序中,当前页面的 URL 与请求资源的 URL 的协议、主机、端口不相同,导致浏览器出于安全考虑限制了对该资源的访问。例如,一个页面使用 Ajax 请求另一个网站的数据,由于协议、主机和端口不同,浏览器会阻止该请求。
 
跨域是一种安全机制,它可以保护 Web 应用程序免受来自其他域的恶意攻击。但有时候我们需要跨域请求数据或资源,这时需要通过一些手段来解决跨域问题,例如使用 JSONP、CORS、代理服务器等方式。
2.5.2 跨域问题处理
Gateway网关通过添加配置解决跨域:
spring:
  cloud:
    gateway:
      globalcors: # 全局的跨域处理
        add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
        corsConfigurations:
          '[/**]':
            allowedOrigins: # 允许哪些网站的跨域请求
              - "http://localhost:XXXX"
            allowedMethods: # 允许的跨域ajax的请求方式
              - "GET"
              - "POST"
              - "DELETE"
              - "PUT"
              - "OPTIONS"
            allowedHeaders: "*" # 允许在请求中携带的头信息
            allowCredentials: true # 是否允许携带cookie
            maxAge: 360000 # 这次跨域检测的有效期
                


















