关于Gateway服务网关的学习

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

上篇文章介绍完Feign远程调用的学习,今天来介绍Gateway网关


提示:以下是本篇文章正文内容,下面案例可供参考

一、Gateway是什么?

官方说法:Spring Cloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等响应式编程和事件流技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。

简单来理解就是网管,去上网,允不允许,上哪台等等都要经过它的管理

有些功能只对内开放,目的是防止某些微服务的接口向外暴露。

网关的核心功能特性

  • 请求路由:根据某些规则,将请求转发某个微服务中,当微服务数量多时,需要负载均衡

  • 权限控制:检验用户是否拥有访问资格

  • 限流:当请求数量多的时候,按照下流微服务能够接收的量去放行请求

二、搭建Gateway网关

1.创建Gateway-service模块

2.导入依赖包

Gateway这个微服务需要被nacos注册

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

3.编写启动类

@SpringBootApplication
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class,args);
    }
}

三、关于Gateway的配置编写

1:在application.yml中编写Gateway的配置

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/,是则录入路由目标地址
        - id: order-service
          uri: lb://orderservice
          predicates:
            - Path=/order/**

来解析一下里面的属性

1:routes:路由

2:id:路由的名字

3:uri:路由的目标地址,当断言提高时会将目标地址替换localhost:10010从而转发到微服务

4:predicates:路由断言,判断是否转发的规则

我们来重点解析predicates

2:predicates的学习

spring为我们提供了11种基本工厂,不需要完全记住,当需要的时候就查询即可

断言的作用可以理解为路由是否向你开启的规则

四、Gateway的内部结构

上面的讲解介绍的是Gateway的入口,就像大门一样,即使你成功进入,内部仍然有许多拦截。

1:Gateway的结构图

从上图不难看出,进入门口(路由)后,后面还有过滤器的存在

过滤器的作用就是对微服务的请求和相应做出处理

2:什么是过滤器 

1:过滤器的作用

过滤器的作用就是对微服务的请求和相应做出处理

那么它是如何处理的呢,先来看一下它的规则

2:过滤器的规则 

下面是过滤器工厂GatewayFilterFactory

以上列出几个常用的规则,无需死记硬背,要使用的时候可以上spring官网查阅

过滤器有三种

1:路由过滤器

2:默认过滤器

3:全局过滤器

首先是默认过滤器

3:路由过滤器

路由过滤器顾名思义是只针对某个路由的,下面是它的配置方式

  - id: order-service
          uri: lb://orderservice
          predicates:
            - Path=/order/**
          filters: # 此路由器的过滤器
            - AddRequestHeader=admin,niubi! # 添加请求头,逗号前是变量名,逗号后是值

为order-service添加过滤器,我们来演示一下

当我们访问网关的时候(访问内容下面会细讲,现在可以理解为访问order-service)它的路由过滤器会自动为请求添加一个请求头,变量名为admin,值为niubi!

在web层通过@RequestHeader注解来获取请求头就可以查看是否成功

    @GetMapping("{orderId}")
    public Order queryOrderByUserId(@PathVariable("orderId") Long orderId, @RequestHeader("admin") String admin) {
        System.out.println(admin);
        // 根据id查询订单并返回
        return orderService.queryOrderById(orderId);
    }

4:默认过滤器

默认过滤器的作用范围是全部的路由,顾名思义就是所有路由都有它的存在。

上文说到路由(门口)不只有一个

下面是默认过滤器的配置

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 地址写死不方便改变
          uri: lb://userservice # 路由的目标地址 lb是负载均衡,后面跟服务名称
          predicates: # 路由断言,判断访问地址是否符合规则
            - Path=/user/** # 路径匹配,是否是/user/,是则录入路由目标地址
        - id: order-service
          uri: lb://orderservice
          predicates:
            - Path=/order/**
          filters: # 此路由器的过滤器
            - AddRequestHeader=admin,niubi! # 添加请求头
      default-filters: #默认过滤器,范围全局-----------------------------------

由于默认过滤器的作用范围是所有路由,所以它的等级比普通的路由过滤器不同,是跟routes一级

这里要十分注意缩进位置

它的配置方式和路由过滤器是一模一样的规则。

spring:
  application:
    name: gateway # 服务名称
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos地址
    gateway:
      routes:
        - id: user-service # 路由id,自定义,唯一
          # uri: http://127.0.0.1:8081 地址写死不方便改变
          uri: lb://userservice # 路由的目标地址 lb是负载均衡,后面跟服务名称
          predicates: # 路由断言,判断访问地址是否符合规则
            - Path=/user/** # 路径匹配,是否是/user/,是则录入路由目标地址
        - id: order-service
          uri: lb://orderservice
          predicates:
            - Path=/order/**
#          filters: # 此路由器的过滤器
      default-filters:
        - AddRequestHeader=admin,niubi! # 添加请求头 #默认过滤器,范围全局

5:全局过滤器

全局过滤器GloalFilters和上面几种不同之处在于你需要完成它的逻辑处理

步骤

新建立一个类实现GlobalFilter接口实现它的方法 

//设置过滤器优先度 越小优先越强 -2147483647-2147473647
@Order(-1)
//交给spring管理
@Component
public class AuthorizeFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //exchange存放着请求信息,chain负责放行到其他过滤器

        //1:获取请求参数
        ServerHttpRequest request = exchange.getRequest();
        MultiValueMap<String, String> queryParams = request.getQueryParams();
        //2:获取参数中的  authorization 参数
        String authorization = queryParams.getFirst("authorization");
        //3:判断参数
        if ("admin".equals(authorization)){
            //4:放行
            return chain.filter(exchange);
        }
        //4:拦截
        //4.1:设置状态码,作用是告诉用户目前状态而不是单纯的被拦截
        ServerHttpResponse response = exchange.getResponse();
        response.setStatusCode(HttpStatus.valueOf(401)); //401模拟未登录的状态
        //4.2:拦截
        return response.setComplete();

//-------------该拦截器作用是判断用户是否登录(是否携带规定的参数)

    }
}

具体效果 

 当没有携带规定参数会提示401状态

当携带了规定参数则会成功访问

五、过滤器的执行顺序 

当编写多个过滤器的时候,Gateway会将他们合并到一个过滤器链(集合)中

它的默认顺序为:默认过滤器--路由过滤器--全局过滤器

但是每一个过滤器都会有一个固定的优先度值order

路由过滤器和默认过滤器的order值由spring 管理,默认为1,存在多个路由过滤器或者默认过滤器时开始递增

而全局过滤器则是可以自定义order值,使用注解定义order,方法如下

当过滤器order值相同时候,它的默认顺序为:默认过滤器--路由过滤器--全局过滤器

六、同一网关Gateway跨域问题

在网关微服务中的配置文件添加

 globalcors: # 全局的跨域处理
        add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题  cors解决方案是浏览器向服务端发送请求是否准许跨域,这个请求是options,所以要放行
        corsConfigurations:
          '[/**]':  # 拦截所有路径
            allowedOrigins: # 允许哪些网站的跨域请求
              - "http://localhost:8090"
              - "http://www.leyou.com"
            allowedMethods: # 允许的跨域ajax的请求方式
              - "GET"
              - "POST"
              - "DELETE"
              - "PUT"
              - "OPTIONS"
            allowedHeaders: "*" # 允许在请求中携带的头信息
            allowCredentials: true # 是否允许携带cookie
            maxAge: 360000 # 这次跨域检测的有效期

 具体用法以后会说到

七、关于Gateway在springcloud的工作流程图

总结

以上是关于Gateway的学习

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值