0
点赞
收藏
分享

微信扫一扫

命令模式:灯开灯关

q松_松q 2024-06-19 阅读 10

gateway-网关

网关

这样的架构,会存在诸多的问题:

  • 每个业务都会需要鉴权、限流、权限校验、跨域等逻辑,如果每个业务都各自为站。自己造轮子实现一遍,完全没必要,完全可以抽离出来,放到一个统一的地方去做
    上面的问题可以借助网关来解决。
    在这里插入图片描述

添加上API网关之后,系统变成三层结构,系统的架构图如下:
在这里插入图片描述
加入网关之后的架构图
在这里插入图片描述

spring cloud gateway

  • 功能特征
  • 基于spring5.0和springboot2.0进行构建
  • 动态路由:可以匹配任何请求属性
  • 支持路径重写
  • 集成服务发现(nacos、ereka)
  • 可集成流控降级功能(sentinel、hystrix)
  • 可以对路由指定易于编写的断言和过滤器
  • 工作原理
    spring cloud gateway的工作原理和zuul的差不多,最大的区别就是gateway的filter只有pre和post两种。

gateway初体验

添加依赖

   <!--添加springcloud gateway依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
  • 配置文件
server:
  port: 8090
# gateway配置
spring:
  application:
    name: api-gateway
  cloud:
    #gateway配置
    gateway:
      #路由规则
      routes:
        - id: order_router #路由的唯一标识,路由到order
          uri: http://localhost:8081 #需要转发的地址
          #断言规则 用于路由规则的匹配
          predicates:
            - Path=/order-server/**
              # http://localhost:8090/order-server/order/buyProduct 路由到↓
              # http://localhost:8081/order-server/order/buyProduct
          filters:
            - StripPrefix=1 #内置过滤器,转发之前去掉第一层路径
            # http://localhost:8081/order-server/order/buyProduct 去掉后 ↓
            # http://localhost:8081/order/buyProduct

gateway整合nacos

server:
  port: 8090
# gateway配置
spring:
  application:
    name: api-gateway
  cloud:
    #nacos配置
    nacos:
      discovery:
        server-addr: 192.168.184.15:8848
        username: nacos
        password: nacos
    #gateway配置
    gateway:
      #路由规则
      routes:
        - id: order_router #路由的唯一标识,路由到order
          uri: lb://order-service #需要转发的地址 lb:使用nacos中的本地负载均衡策略
          #断言规则 用于路由规则的匹配
          predicates:
            - Path=/order-server/**
            # http://localhost:8090/order-server/order/buyProduct 路由到↓
            # http://localhost:8081/order-server/order/buyProduct
          filters:
            - StripPrefix=1 #内置过滤器,转发之前去掉第一层路径
            # http://localhost:8081/order-server/order/buyProduct 去掉后 ↓
            # http://localhost:8081/order/buyProduct

简写方式

当服务注册到nacos后,断言规则可以用服务名来进行匹配,此时配置可以进行简化(约定服务名和断言规则都从nacos获取)

server:
  port: 8090
# gateway配置
spring:
  application:
    name: api-gateway
  cloud:
    #nacos配置
    nacos:
      discovery:
        server-addr: 192.168.184.15:8848
        username: nacos
        password: nacos
    #gateway配置
    gateway:
     discovery:
       locator:
         enabled: true #是否启动自动识别nacos服务(约定大于配置)
  • 测试
    此时访问:http://localhost:8090/order-service/order/buyProduct
    在这里插入图片描述

内置路由断言工厂

内置断言工厂

在这里插入图片描述
在这里插入图片描述

  • 基于Datetime类型的断言工厂
    此类型的断言根据时间做判断,主要有三个:
  • AfterRoutePredicateFactory:接收一个日期参数,判断请求日期是否晚于指定日期
  • BeforeRoutePredicateFactory:接收一个日期参数,判断请求日期是否早于指定日期
  • BetweenRoutePredicateFactory:接收一个日期参数,判断请求日是否在指定时间段内
    类型:zoneDateTime.now():System.out.println(ZonedDateTime.now());
#第一版
server:
  port: 8090
# gateway配置
spring:
  application:
    name: api-gateway
  cloud:
    #gateway配置
    gateway:
      #路由规则
      routes:
        - id: order_router #路由的唯一标识,路由到order
          uri: http://localhost:8081 #需要转发的地址
          #断言规则 用于路由规则的匹配
          predicates:
            - Path=/order/**
            - After=2024-12-31T23:59:59.789+08:00[Asia/Shanghai]
  • 基于请求头Headder的断言工厂
  • HeaderRoutePredicateFactory:接收两个参数,标题名称和正则表达式,判断请求Header是否具有给定名称且值与正则表达式匹配。
#第一版
server:
  port: 8090
# gateway配置
spring:
  application:
    name: api-gateway
  cloud:
    #nacos配置
    nacos:
      discovery:
        server-addr: 192.168.184.15:8848
        username: nacos
        password: nacos
    #gateway配置
    gateway:
      #路由规则
      routes:
        - id: order_router #路由的唯一标识,路由到order
          uri: http://localhost:8081 #需要转发的地址
          #断言规则 用于路由规则的匹配
          predicates:
            - Path=/order/**
            - After=2023-12-31T23:59:59.789+08:00[Asia/Shanghai]
            - Header=X-Request-Id,\d+

测试
在这里插入图片描述
在这里插入图片描述

  • 基于Method请求方法的断言工厂
  • MethodRoutePredicateFactory:接收一个参数,判断请求类型是否跟指定的类型匹配
#第一版
server:
  port: 8090
# gateway配置
spring:
  application:
    name: api-gateway
  cloud:
    #nacos配置
    nacos:
      discovery:
        server-addr: 192.168.184.15:8848
        username: nacos
        password: nacos
    #gateway配置
    gateway:
      #路由规则
      routes:
        - id: order_router #路由的唯一标识,路由到order
          uri: http://localhost:8081 #需要转发的地址
          #断言规则 用于路由规则的匹配
          predicates:
            - Path=/order/**
            - After=2023-12-31T23:59:59.789+08:00[Asia/Shanghai]
            - Header=X-Request-Id,\d+
            - Method=GET

  • 基于Query请求参数的断言工厂
  • QueryRoutePredicateFactory:接收两个参数,请求param和正则表达式,判断请求参数是否具有给定名称且值与正则表达式匹配。
#第一版
server:
  port: 8090
# gateway配置
spring:
  application:
    name: api-gateway
  cloud:
    #nacos配置
    nacos:
      discovery:
        server-addr: 192.168.184.15:8848
        username: nacos
        password: nacos
    #gateway配置
    gateway:
      #路由规则
      routes:
        - id: order_router #路由的唯一标识,路由到order
          uri: http://localhost:8081 #需要转发的地址
          #断言规则 用于路由规则的匹配
          predicates:
            - Path=/order/**
            - After=2023-12-31T23:59:59.789+08:00[Asia/Shanghai]
            - Header=X-Request-Id,\d+
            - Method=GET
            - Query=id,\d+

测试
在这里插入图片描述

自定义路由断言工厂

1、必须是bean组件
2、由于约定大于配置:类名必须加上RoutePredicateFactory作为结尾
3、必须继承AbstractRoutePredicateFactory类
4、必须声明一个静态内部类,声明属性来接收配置文件中对应的信息
5、需要结合shortcutFieldOrder来进行绑定
6、通过apply进行逻辑判断,true就是匹配成功,false匹配失败

自定义路由工厂

  • 配置文件
#第一版
server:
  port: 8090
# gateway配置
spring:
  application:
    name: api-gateway
  cloud:
    #nacos配置
    nacos:
      discovery:
        server-addr: 192.168.184.15:8848
        username: nacos
        password: nacos
    #gateway配置
    gateway:
      #路由规则
      routes:
        - id: order_router #路由的唯一标识,路由到order
          uri: http://localhost:8081 #需要转发的地址
          #断言规则 用于路由规则的匹配
          predicates:
            - Path=/order/**
            - After=2023-12-31T23:59:59.789+08:00[Asia/Shanghai]
            - Header=X-Request-Id,\d+
            - Method=GET
            - Query=id,\d+
            - CheckAuth=zzq
  • 自定义代码
@Component
public class CheckAuthRoutePredicateFactory extends AbstractRoutePredicateFactory<CheckAuthRoutePredicateFactory.Config> {


    public CheckAuthRoutePredicateFactory() {
        super(CheckAuthRoutePredicateFactory.Config.class);
    }

    /**
     * 绑定配置信息
     * @return
     */
    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("name");
    }

    public Predicate<ServerWebExchange> apply(Config config) {
        return new GatewayPredicate() {
            @Override
            public boolean test(ServerWebExchange exchange) {
                if (config.getName().equals("zzq")){
                    return true;
                }
                return false;
            }
        };
    }

    /**
     * 用于接收配置文件中 断言的信息
     */
    @Validated
    @Data
    public static class Config {
        private String name;
    }
}

  • 测试
    在这里插入图片描述
  • 修改配置后
#第一版
server:
  port: 8090
# gateway配置
spring:
  application:
    name: api-gateway
  cloud:
    #nacos配置
    nacos:
      discovery:
        server-addr: 192.168.184.15:8848
        username: nacos
        password: nacos
    #gateway配置
    gateway:
      #路由规则
      routes:
        - id: order_router #路由的唯一标识,路由到order
          uri: http://localhost:8081 #需要转发的地址
          #断言规则 用于路由规则的匹配
          predicates:
            - Path=/order/**
            - After=2023-12-31T23:59:59.789+08:00[Asia/Shanghai]
            - Header=X-Request-Id,\d+
            - Method=GET
            - Query=id,\d+
            - CheckAuth=qwee
  • 测试
    在这里插入图片描述

内置/自定义过滤器

典型内置过滤器

  • 添加请求头
#第一版
server:
  port: 8090
# gateway配置
spring:
  application:
    name: api-gateway
  cloud:
    #nacos配置
    nacos:
      discovery:
        server-addr: 192.168.184.15:8848
        username: nacos
        password: nacos
    #gateway配置
    gateway:
      #路由规则
      routes:
        - id: order_router #路由的唯一标识,路由到order
          uri: http://localhost:8081 #需要转发的地址
          #断言规则 用于路由规则的匹配
          predicates:
            - Path=/order/**
            - After=2023-12-31T23:59:59.789+08:00[Asia/Shanghai]
            - Header=X-Request-Id,\d+
            - Method=GET
            - Query=id,\d+
            - CheckAuth=zzq
          filters:
            - AddRequestHeader=X-Request-color,red #添加请求头
  • 为匹配的路由添加统一前缀
    在这里插入图片描述
  • order.yml配置context-path
server:
  port: 8081
  servlet:
    context-path: /shanghaiserver
  • gateway为了适配添加前缀
#第一版
server:
  port: 8090
# gateway配置
spring:
  application:
    name: api-gateway
  cloud:
    #nacos配置
    nacos:
      discovery:
        server-addr: 192.168.184.15:8848
        username: nacos
        password: nacos
    #gateway配置
    gateway:
      #路由规则
      routes:
        - id: order_router #路由的唯一标识,路由到order
          uri: http://localhost:8081 #需要转发的地址
          #断言规则 用于路由规则的匹配
          predicates:
            - Path=/order/**
            - After=2023-12-31T23:59:59.789+08:00[Asia/Shanghai]
            - Header=X-Request-Id,\d+
            - Method=GET
            - Query=id,\d+
            - CheckAuth=zzq
          filters:
            - AddRequestHeader=X-Request-color,red #添加请求头
            - PrefixPath=/shanghaiserver  #添加前缀  对应微服务需要配置context-path

自定义过滤器

  • 自定义过滤器
package com.springcloudalibaba.gateway.config;

import com.alibaba.nacos.api.utils.StringUtils;
import lombok.Data;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Arrays;
import java.util.List;

/**
 * @author : zhouzhiqiang
 * @date : 2024/6/19 12:51
 * @description :
 */
@Component
public class CheckParamGatewayFilterFactory extends AbstractGatewayFilterFactory<CheckParamGatewayFilterFactory.Config> {

    public CheckParamGatewayFilterFactory() {
        super(CheckParamGatewayFilterFactory.Config.class);
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("name");
    }

    @Override
    public GatewayFilter apply(Config config) {
        return new GatewayFilter() {
            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                String name = exchange.getRequest().getQueryParams().getFirst("name");
                if (!StringUtils.isBlank(name)) {
                    //如果相等请求被放过
                    if (config.getName().equals(name)) {
                        return chain.filter(exchange);
                    } else {
                        //如果不相等返回404
                        exchange.getResponse().setStatusCode(HttpStatus.NOT_FOUND);
                        return exchange.getResponse().setComplete();
                    }
                }
                return chain.filter(exchange);
            }
        };
    }

    /**
     * 用于接收配置文件中 过滤器的信息
     */
    @Validated
    @Data
    public static class Config {
        private String name;
    }
}

  • 配置自定义的过滤器工厂
#第一版
server:
  port: 8090
# gateway配置
spring:
  application:
    name: api-gateway
  cloud:
    #nacos配置
    nacos:
      discovery:
        server-addr: 192.168.184.15:8848
        username: nacos
        password: nacos
    #gateway配置
    gateway:
      #路由规则
      routes:
        - id: order_router #路由的唯一标识,路由到order
          uri: http://localhost:8081 #需要转发的地址
          #断言规则 用于路由规则的匹配
          predicates:
            - Path=/order/**
            - After=2023-12-31T23:59:59.789+08:00[Asia/Shanghai]
            - Header=X-Request-Id,\d+
            - Method=GET
            - Query=id,\d+
            - CheckAuth=zzq
          filters:
            - AddRequestHeader=X-Request-color,red #添加请求头
            - PrefixPath=/shanghaiserver  #添加前缀  对应微服务需要配置context-path
            - CheckParam=zzq
  • 测试
  • 成功
    在这里插入图片描述
  • 失败
    在这里插入图片描述

全局过滤器

举报

相关推荐

0 条评论