Gateway网关详解

Gateway网关

1.网关作用介绍

对微服务起到保护的作用

  • 身份认证和权限校验
  • 服务路由、负载均衡
  • 请求限流
2.网关的技术实现

在SpringCloud中网关的实现包括两种

  • gateway
  • zuul

Zuul是基于Servlet的实现,属于阻塞式编程。而SpringCloudGateway是基于Spring5中提供的WebFlux,属于响应式编程的实现,具备更好的性能

3. 快速入门
  • 搭建网关服务
  • 创建一个新的module,起名为gateway
  • 在pom.xml文件中引入依赖
  •       <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>
    
  • 配置启动类
  •   package cn.itcast;
      ​
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      ​
      @SpringBootApplication
      public class GatewayApplication {
          public static void main(String[] args) {
              SpringApplication.run(GatewayApplication.class, args);
          }
      }
      ​
    
  • 在application中添加配置
  •   server:
        port: 10010
      spring:
        application:
          name: gateway
        cloud:
          nacos:
            server-addr: localhost:8848 # nacos地址
          gateway:
            routes:
             - id: user-service # 路由标识,必须唯一
               uri: lb://userservice # 路由的目标地址
               predicates: # 路由断言,判断请求是否符合规则
                 - Path=/user/** # 路由断言,判断路径是否是以/user开头,如果是则符合
             - id: order-service
               uri: lb://orderservice
               predicates:
                 - Path=/order/**
    
  • 测试发现,当我们访问http://127.0.0.1:10010/user/1或者http://127.0.0.1:10010/order/102可以访问成功
  • 原理图
  • image.png
4.路由断言工厂
  • 路由断言工厂(Route Predicate Factory)的作用:读取用户定义的断言条件,对请求做出判断
  • Path=/user/**是什么含义:路径是以/user开头的就认为是符合的
  • image.png
5.路由过滤器
  • 作用:可以对进入网关的请求和微服务返回的响应做处理
  • 案例:给所有进入userservice的请求添加一个请求头
  • 实现方式:在gateway中修改application.yml文件,给userservice的路由添加过滤器
  •   spring:
        application:
          name: gateway
        cloud:
          nacos:
            server-addr: localhost:8848 # nacos地址
          gateway:
            routes:
             - id: user-service # 路由标识,必须唯一
               uri: lb://userservice # 路由的目标地址
               predicates: # 路由断言,判断请求是否符合规则
                 - Path=/user/** # 路由断言,判断路径是否是以/user开头,如果是则符合
               filters:
                 - AddRequestHeader=Truth, Itcast is freaking awesome! # 过滤器
             - id: order-service
               uri: lb://orderservice
               predicates:
                 - Path=/order/**
    
  • 上方是只针对一个服务的过滤器,只针对userservice。下方为针对所有节点的过滤器
  •   spring:
        application:
          name: gateway
        cloud:
          nacos:
            server-addr: localhost:8848 # nacos地址
          gateway:
            routes:
             - id: user-service # 路由标识,必须唯一
               uri: lb://userservice # 路由的目标地址
               predicates: # 路由断言,判断请求是否符合规则
                 - Path=/user/** # 路由断言,判断路径是否是以/user开头,如果是则符合
             - id: order-service
               uri: lb://orderservice
               predicates:
                 - Path=/order/**
            default-filters: # 默认过滤器
              - AddRequestHeader=Truth, Itcast is freaking awesome! # 请求头
    
  • 在Controller中获取请求头
  •       @GetMapping("/{id}")
          public User queryById(@PathVariable("id") Long id,
                                @RequestHeader(value = "Truth", required = false) String Truth) {
              System.out.println("truth:" + Truth);
              return userService.queryById(id);
          }
    
  • 访问userservice会发现控制台中打印出了,truch:Truth, Itcast is freaking awesome!
6.全局过滤器
  • 作用:处理一切进入网关的请求和微服务响应
  • 案例:新建过滤器Controller,命名为AuthorizeFilter
  •   package cn.itcast.gateway;
      ​
      import org.springframework.cloud.gateway.filter.GatewayFilterChain;
      import org.springframework.cloud.gateway.filter.GlobalFilter;
      import org.springframework.core.annotation.Order;
      import org.springframework.http.HttpStatus;
      import org.springframework.http.server.reactive.ServerHttpRequest;
      import org.springframework.stereotype.Component;
      import org.springframework.util.MultiValueMap;
      import org.springframework.web.server.ServerWebExchange;
      import reactor.core.publisher.Mono;
      ​
      @Order(-1)  // 项目中可能存在多个过滤器,order的值代表优先级,值越小越先执行
      @Component
      public class AuthorizeFilter implements GlobalFilter {
      ​
          @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.效验
              if ("admin".equals(auth)) {
                  // 4.是,放行
                  return chain.filter(exchange);
              }
              // 5.拦截
              // 5.1.禁止访问
              exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
              // 5.2.结束处理
              return exchange.getResponse().setComplete();
          }
      }
    
  • 测试
    image.png

image.png

7.过滤器链执行顺序
  • 请求进入网关会碰到三类过滤器:当前路由的过滤器、DefaultFilter、GlobalFilter
  • 请求路由后,会将当前路由过滤器和DefaultFilter、GlobalFilter,和并到一个过滤器链(集合)中,排序后依次执行每个过滤器
  • 每一个过滤器都必须指定一个int类型的order值,order值越小,优先级越高,执行顺序越靠前
  • GlobalFilter通过实现Ordered接口,或者添加@Order注解来指定order值,由我们自己指定
  • 路由过滤器和defaultFilter的order由Spring指定,默认是按照声明顺序从1递增
  • 当过滤器的order值一样时,会按照defaultFilter>路由过滤器>GlobalFilter的顺序执行
  • 可以参考下面几个类的源码来查看
    image.png
8.网关的cors跨域配置
  • 在gateway项目下的application中添加配置
  •   spring:
        cloud:
          gateway:
            globalcors: # 全局的跨域处理
              add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
              corsConfigurations:
                '[/**]':
                  allowedOrigins: # 允许哪些网站的跨域请求
                    - "http://localhost:8090"
                    - "http://127.0.0.1:5500"
                    - "http://www.leyou.com"
                  allowedMethods: # 允许的跨域ajax的请求方式
                    - "GET"
                    - "POST"
                    - "DELETE"
                    - "PUT"
                    - "OPTIONS"
                  allowedHeaders: "*" # 允许在请求中携带的头信息
                  allowCredentials: true # 是否允许携带cookie
                  maxAge: 360000 # 这次跨域检测的有效期
    
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

栖迟于一丘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值