Gateway Spring Cloud API网关组件-学习记录

Gateway Spring Cloud API网关组件

一、什么是Gateway ?

1.概念:
Gateway 微服务中间件,网关就像整个微服务系统的门面一样,是系统对外的唯一入口。有了它,客户端会先将请求发送到 API 网关,然后由 API 网关根据请求的标识信息将请求转发到微服务实例。
2.为什么要使用gateway?
在微服务架构中,一个系统往往由多个微服务组成,而这些服务可能部署在不同机房、不同地区、不同域名下。同时,在需要登录认证、授权方面的信息无法在各服务之间共享,以及可能存在跨域等问题就出现了,这个时候就可以通过 API 网关来解决这些问题。

Gateway Spring Cloud API网关组件-学习记录_第1张图片
3.工作原理
客户端向 Spring Cloud 网关发出请求。如果网关处理程序映射确定请求与路由匹配,则会将其发送到网关 Web 处理程序。 此处理程序通过特定于请求的筛选器链运行请求。 筛选器用虚线划分的原因是筛选器可以在发送代理请求之前和之后运行逻辑。 执行所有“预”过滤器逻辑。然后发出代理请求。发出代理请求后,将运行“post”筛选器逻辑。
Gateway Spring Cloud API网关组件-学习记录_第2张图片

二、入门使用

1、搭建Spring Cloud项目以及相关的依赖

搭建过程省略,项目结果图如下:
其中使用了nacos服务治理和feign远程调用服务,其使用在我之前的笔记中已经详细记录了
Spring cloud 集成nacos实现服务注册、发现和调用 — 详细笔记
spring cloud nacos配置管理— 学习笔记
Spring cloud ---- openfeign实现远程调用 学习笔记
Gateway Spring Cloud API网关组件-学习记录_第3张图片

2、配置服务信息

在gateway的工程里面的application.yml文件中配置:
参考官网
Gateway Spring Cloud API网关组件-学习记录_第4张图片
我的配置如下:

server:
  port: 7777
spring:
  application:
    name: gatewayService
  cloud:
  	# gateway也是一个服务,也需要注册到nacos中心
    nacos:
      server-addr: localhost:8848
    # 在这里配置gateway的配置
    gateway:
      # 路由信息,
      routes:
      	# 路由id,唯一,自定义,尽量和对应的服务名称相联系
        - id: order-service
          # 服务的uri,lb代表负载均衡,
          uri: lb://orderserver
          # 路由断言,意思是满足这个下面的断言才能进行路由转发到对应的服务
          predicates:  # 相关的配置后面在看
            - Path=/orders/**
        - id: user-service
          uri: lb://userserver
          predicates:
            - Path=/user/**
      default-filters:
      global-filter:

3、启动全部服务并测试

注意:提前将nacos启动
Gateway Spring Cloud API网关组件-学习记录_第5张图片
在nacos中可以看到五个服务

Gateway Spring Cloud API网关组件-学习记录_第6张图片

(1)先通过postman测试直接访问服务(不通过gateway)看是否正常启动

Gateway Spring Cloud API网关组件-学习记录_第7张图片

(2)通过gateway来访问服务

Gateway Spring Cloud API网关组件-学习记录_第8张图片
至此,gateway入门搭建成功

三、断言工厂

官网断言工厂地址
满足自己设置的所有的断言才能转发到对应的服务上去。

从下图可以看到一共12个断言,跑2个试试,剩下的用到了再去官网看就行
Gateway Spring Cloud API网关组件-学习记录_第9张图片

1、Path Route Predicate Factory

路径路由断言工厂

路由匹配规则,如:- Path=/orders/** 则代表请求当中携带orders就可以。
多个匹配规则用逗号隔开之间,如下:
spring:
  cloud:
    gateway:
      routes:
      - id: path_route
        uri: https://example.org
        predicates:
        # 这里需要满足携带red以及有一个参数在,形如:/red/1
        - Path=/red/{segment},/blue/{segment}

2、Between Route Predicate Factory

作用:设置请求的时间要在某个时间区间内

spring:
  cloud:
    gateway:
      routes:
      - id: between_route
        uri: https://example.org
        predicates:
        # [America/Denver]这个代表美国时区, Asia/Shanghai 代表中国上海
        - Between=Between=2017-01-20T17:42:47.443+08:00[Asia/Shanghai], 2023-02-26T08:00:00.443+08:00[Asia/Shanghai]

Gateway Spring Cloud API网关组件-学习记录_第10张图片
图中的时间是在2017.1.20的17:42:47到2023-02-26的08:00:00这个时间范围内,而从图中看到我此时的时间是2023-2-26的10:58已经不在这个时间范围内了,下面测试一下
结果:
Gateway Spring Cloud API网关组件-学习记录_第11张图片
显示404,没有数据说明没有转发到对应的服务去,下面我再改成在这个时间戳的
改到了2-28,在进行测试

Gateway Spring Cloud API网关组件-学习记录_第12张图片
结果:
Gateway Spring Cloud API网关组件-学习记录_第13张图片
大体就是这样的,参考官网进行使用就行

更多的可以在官网进行查看
Gateway Spring Cloud API网关组件-学习记录_第14张图片

四、过滤器

1、路由过滤器

还是举例使用2个,剩下的看一下,在需要的时候去官网看
官网路由过滤器工厂地址
Gateway Spring Cloud API网关组件-学习记录_第15张图片

(1)AddRequestHeader GatewayFilter Factory

在请求头里面添加参数

server:
  port: 7777
spring:
  application:
    name: gatewayService
  cloud:
    nacos:
      server-addr: localhost:8848
    gateway:
      routes:
        - id: order-service
          uri: lb://orderserver
          predicates:
            - Path=/orders/**
            - Between=2017-01-20T17:42:47.443+08:00[Asia/Shanghai], 2023-02-28T08:00:00.443+08:00[Asia/Shanghai]
          filters:
            # 这就是在请求头里面放了一个myHeader,里面的值为20020305
            - AddRequestHeader=myHeader,20020305
        - id: user-service
          uri: lb://userserver
          predicates:
            - Path=/user/**

重启相关的服务后,在controller里面取出这个值,看是否能取到

Gateway Spring Cloud API网关组件-学习记录_第16张图片
运行结果:
Gateway Spring Cloud API网关组件-学习记录_第17张图片

(2)AddRequestParameter GatewayFilter Factory

和上面的有点像,都是在请求里面加东西然后再发送到对应的服务上去

添加一个parameter:name=wlh
Gateway Spring Cloud API网关组件-学习记录_第18张图片

从controller取出值

Gateway Spring Cloud API网关组件-学习记录_第19张图片
发起请求查看运行结果:
Gateway Spring Cloud API网关组件-学习记录_第20张图片
Gateway Spring Cloud API网关组件-学习记录_第21张图片

2、默认过滤器 Default Filters

默认过滤器就所有的路由都会执行

(1)添加默认过滤器配置

Gateway Spring Cloud API网关组件-学习记录_第22张图片

(2)修改controller层

Gateway Spring Cloud API网关组件-学习记录_第23张图片

(3)测试数据

Gateway Spring Cloud API网关组件-学习记录_第24张图片

查看控制台输出:
Gateway Spring Cloud API网关组件-学习记录_第25张图片

3、全局过滤器 Global Filters

效果和默认过滤器一样,所有的router都要经过这个过滤器,但是这个是需要我们自己去实现这个过滤器的方法的:实现GlobalFilter 接口

MyGlobalFilterConfig:

package space.lkiku.config;


import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * @Classname MyGlobalFilter
 * @Description TODO Gateway全局过滤器
 * @Version 1.0.0
 * @Date 2023/2/26 14:31
 * @Created by wlh12
 */
@Order(Integer.MIN_VALUE) // 设置过滤器的权重,越小越先执行。
@Configuration
public class MyGlobalFilterConfig implements GlobalFilter {

    /**
     *  过滤逻辑和之前的一样,有一些使用不太一样
     * @param exchange 请求上下文,可以从里面拿到request和response
     * @param chain 放行(和servlet的filter放行一样)
     * @return
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // request
        ServerHttpRequest request = exchange.getRequest();
        // response
        ServerHttpResponse response = exchange.getResponse();
        /**
         * 模拟请求中存在token才放行
         */
        // 从request获取携带的数据信息
        HttpHeaders headers = request.getHeaders();
        // 获取第一个满足的
        String token = headers.getFirst("Authorization");
        if (token!=null && !token.equals("")){
            // 放行 使用chain.filter(exchange),返回类型为Mono
            return chain.filter(exchange);
        }
        // 否则拦截,设置code码 HttpStatus是一个http的枚举类UNAUTHORIZED为401
        response.setStatusCode(HttpStatus.UNAUTHORIZED);
        return response.setComplete();
    }
}

重启服务,进行测试:
Gateway Spring Cloud API网关组件-学习记录_第26张图片

4、过滤器执行顺序

目前一共有三类。
第一类:路由过滤器(GatewayFilter)在哪个路由上设置了,哪个路由才会执行此过滤器
第二类:默认过滤器(DefaultFilter)默认所有的路由(router)都会执行该类过滤器
第三类:全局过滤器(GlobalFilter),和第二类有点类似,但是时需要我们自定义的

设置过滤器的权重:

Gateway Spring Cloud API网关组件-学习记录_第27张图片
总结:
1.每个过滤器都可以指定一个int类型的值,表示该过滤器的权重,通过权重的大小来决定执行顺序
2.当多个过滤器的权重值相同的时候,默认的顺序是default先执行,然后是路由过滤器,最后是全局过滤器

Gateway Spring Cloud API网关组件-学习记录_第28张图片

5、小结

小结:上述的三类过滤器的基本使用都差不多了,对于不同过滤器工厂可以参考官网的示例。对于过滤器的使用就差不多这样了

需要注意的是默认过滤器和路由过滤器都是可以通过自定义配置的形式来实现的

Gateway Spring Cloud API网关组件-学习记录_第29张图片

查看官方示例

五、路由元数据配置

使用元数据为每个路由配置其他参数,如下所示:

spring:
  cloud:
    gateway:
      routes:
      - id: route_with_metadata
        uri: https://example.org
        # matedata 配置元数据
        metadata:
          optionName: "OptionValue"
          compositeObject:
            name: "value"
          iAmNumber: 1

获取元数据(从请求的上下文中):

Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
// get all metadata properties 获取全部元数据
route.getMetadata();
// get a single metadata property 根据指定的key获取元数据
route.getMetadata(someKey);

测试通过

Gateway Spring Cloud API网关组件-学习记录_第30张图片

六、Http超时配置

可以为所有路由配置 http 超时(响应和连接),并为每个特定路由覆盖。
response-timeout: 响应超时配置
connect-timeout: 连接超时配置

1、全局配置

配置全局 http 超时:
连接必须以毫秒为单位指定。
如:

spring:
  cloud:
    gateway:
      httpclient:
        connect-timeout: 1000
        response-timeout: 5s

2、每个路由配置超时

配置每个路由超时:
连接和响应都必须以毫秒为单位指定。
配置在元数据下

          metadata:
            optionName: "OptionValue"
            compositeObject:
              name: "value"
            iAmNumber: 1
            connect-timeout: 10000
            response-timeout:

如图:
Gateway Spring Cloud API网关组件-学习记录_第31张图片

七、CORS配置(解决跨域)

跨域:一个请求url的协议域名端口三者之间任意一个与当前页面url不同即为跨域。
例如:在本机上,前端项目是localhost:8000,后端是8080,那么在前端发起请求到后端的就属于跨域。

产生跨域问题的原因: 出于浏览器的同源策略限制。同源策略是一个重要的安全策略,它用于限制一个origin的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档,减少可能被攻击的媒介。

CORS解决跨域的原理: 在请求的时候会发请求询问后端的服务是否允许跨域,请求类型为options。

因此可以分析需要配置哪些信息:

首先我们是因为前端的请求发送到后端跨域了,所以要配置允许前端的进行跨域,然后会有各种各样的请求如post、get等等请求类型,可以设置我们后端有的请求类型(方法),以及对于这次允许跨域可以管多长时间,毕竟每次都去询问能不能跨域会消耗性能,同时当你允许跨域之后也需要把请求头、cookie信息允许跨域 。
需要配置的信息:
1.允许跨域的信息
2.允许跨域的方法
3.单次设置的跨域可以管多久
4.设置携带的请求头
5.设置是否可以携带请求的cookie

因此,大体的配置就如下图(模板)

Gateway Spring Cloud API网关组件-学习记录_第32张图片

你可能感兴趣的:(spring,boot,Spring,cloud,spring,cloud,gateway,学习)