百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程网 > 正文

SpringCloud学习笔记(四)

yuyutoo 2025-02-15 18:05 5 浏览 0 评论

7.GateWay网关

7.1. 简介

  • Spring Cloud Gateway是Spring Cloud生态系统中的网关组件,用于提供路由、过滤、限流等功能。Spring Cloud Gateway基于Spring6、Spring Boot3和Project Reactor等技术。它旨在为微服务架构提供简单有效的统一API路由管理。
  • 核心是一系列的过滤器,通过这些过滤器可以将客户端的请求转发到对应的微服务。是加在整个微服务最前沿的防火墙和代理期,隐藏微服务节点IP端口信息,加强安全保护。
  • Spring Cloud Gateway本身也是微服务,需要注册进服务注册中心。

7.2.网关定位

  • GateWay VS Nginx:Nginx位于客户端和服务器之间,用于反向代理和负载均衡,而Spring Cloud Gateway位于微服务和Nginx之间,用于路由、过滤和限流。

7.3. GateWay三大核心

  • 路由:路由是GateWay中最基础的功能,它将客户端的请求转发到对应的微服务。由ID、URI、断言、过滤器组成,如果断言为true则匹配该路由。
  • 断言:断言是GateWay中用于判断请求是否满足特定条件的机制,开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),只有满足条件的请求才会被转发到对应的微服务。
  • 过滤:过滤是GateWay中用于处理请求和响应的机制,它可以在请求被路由前或者之后对请求进行处理。

7.4. GateWay工作流程

  • 客户端向GateWay发送请求,GateWay根据请求的路径和路由规则,将请求发送到WebHandler。Handler通过指定的过滤器链来将请求发送给对应的微服务。
  • 过滤器可能会在发送代理之前或之后执行业务逻辑。
  • "pre"类型的过滤可以做参数校验、权限校验、流量监控、日志输出、协议转换等,
  • "post"类型的过滤器可以做响应内容、响应头的修改,日志的输出,流量监控等有着非常重要的作用。

7.5. GateWay路由配置

  • 配置文件
server:
  port: 9527

spring:
  application:
    name: cloud-gateway
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
  gateway:
    routes:
      - id: payment_route1
#          uri: http://localhost:9001
        uri: lb://nacos-pay-provider #动态路由,直接寻找微服务,支持负载均衡
        predicates:
          - Path=/pay/gateway/get/**
      - id: payment_route2
#          uri: http://localhost:9001
        uri: lb://nacos-pay-provider
        predicates:
          - Path=/pay/gateway/info/**
  • openfeign配置
@FeignClient(value = "cloud-gateway") //微服务对应网关
public interface PayFeignApi {

    @GetMapping("/pay/nacos/{id}")
    public ResultData getPayInfo(@PathVariable("id") Integer id);

    @GetMapping(value="/pay/micrometer/{id}")
    public String myMicrometer(@PathVariable("id") Integer id);

    @GetMapping("/pay/gateway/get/{id}")
    public ResultData getById(@PathVariable("id") Integer id);

    @GetMapping("/pay/gateway/info")
    public ResultData getInfo();
}

客户端发送请求后,openfeign会寻找对应网关,成功访问9527端口下的 /pay/gateway/get/**/pay/gateway/info/**,请求会被转发到9001端口。

7.6. GateWay断言

  • Path:路径断言,用于匹配请求路径。例如,Path=/pay/gateway/get/**表示匹配所有以/pay/gateway/get/开头的请求路径。
  • After:时间断言,用于匹配请求时间。例如,After=2022-01-01T00:00:00.000+0000表示匹配在2022年1月1日00:00:00之后发出的请求。
  • Before:时间断言,用于匹配请求时间。例如,Before=2022-01-01T00:00:00.000+0000表示匹配在2022年1月1日00:00:00之前发出的请求。
  • Cookie:Cookie断言,用于匹配请求中的Cookie。例如,Cookie=username,zzyy表示匹配Cookie中包含username=zzyy的请求。
  • Header: Header断言,用于匹配请求头。例如,Header=X-Request-Id, \d+表示匹配请求头中包含X-Request-Id且其值为数字的请求。
  • Host: 匹配请求的主机名。例如,Host=**.zzyy.com表示匹配所有以.zzyy.com结尾的主机名。
  • Query: 匹配请求的查询参数。例如,Query=username, \d+表示匹配查询参数中包含username=整数的请求。例如请求为/pay/gateway/get/1?username=1,则匹配成功。
  • RemoteAddr: 匹配请求的远程地址。例如,RemoteAddr=192.168.1.1/24表示匹配来自192.168.1.0/24网段的请求。
  • Metthod: 匹配请求的方法。例如,Method=GET表示匹配GET请求。

示例代码:

server:
  port: 9527

spring:
  application:
    name: cloud-gateway
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
  gateway:
    routes:
      - id: payment_route1
#          uri: http://localhost:9001
        uri: lb://nacos-pay-provider #动态路由,直接寻找微服务,支持负载均衡
        predicates:
          - Path=/pay/gateway/get/**
          - After=2025-02-05T15:08:30.031606300+08:00[Asia/Shanghai]
          - Cookie=username,zzyy
          - Header=X-Request-Id, \d+
          - Host=**.zzyy.com
          - Query=username, \d+
          - RemoteAddr=192.168.83.1/24
          - Method=GET, POST
      - id: payment_route2
#          uri: http://localhost:9001
        uri: lb://nacos-pay-provider
        predicates:
          - Path=/pay/gateway/info/**

7.7. GateWay自定义断言

7.7.1. 自定义步骤

  1. 新建类名以RoutePredicateFactory结尾,继承AbstractRoutePredicateFactory
  2. 重写apply方法
  3. 新建apply方法所需要的静态内部类MyRoutePredicateConfig,这个是路由断言规则
  4. 空参构造方法,内部调用super
  5. 重写apply方法第二版

7.7.2. 代码实现

  1. 编写自定义断言类
@Component
public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory {


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

    @Override
    public Predicate apply(Config config) {
        return new Predicate() {
            @Override
            public boolean test(ServerWebExchange serverWebExchange) {
                String userType = serverWebExchange.getRequest().getQueryParams().getFirst("userType");
                if (userType == null) {
                    return false;
                }
                if (userType.equalsIgnoreCase(config.getUserType())) {
                    return true;
                }
                return false;
            }
        };
    }

    public static class Config {
        @Setter@Getter@NotEmpty
        private String userType; //用户等级
    }
    # 支持短格式书写配置
    @Override
    public List shortcutFieldOrder() {
        return Collections.singletonList("userType");
    }
}
  1. 编写配置文件
server:
  port: 9527

spring:
  application:
    name: cloud-gateway
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
  gateway:
    routes:
      - id: payment_route1
#          uri: http://localhost:9001
        uri: lb://nacos-pay-provider #动态路由,直接寻找微服务,支持负载均衡
        predicates:
          - Path=/pay/gateway/get/**
#            - name: My
#              args:
#                userType: diamond
          - My=diamond

7.8. GateWay过滤器

7.8.1. 过滤器的作用

  • 过滤器可以在请求被路由之前或之后对请求进行修改,或者对路由的请求响应进行修改。

7.8.2. GateWay内置过滤器

  • 过滤器类型 GatewayFilter GlobalFilter 自定义Filter
  • 过滤器作用范围 单个路由 全局

7.8.3. GateWay常用内置过滤器

1.RequestHeader:

  • AddRequestHeader:添加请求头
  • RemoveRequestHeader:移除请求头
  • SetRequestHeader:设置请求头

2.RequestParameter:

  • AddRequestParameter:添加请求参数
  • RemoveRequestParameter:移除请求参数
  • SetRequestParameter:设置请求参数

3.ResponseHeader:

  • AddResponseHeader:添加响应头
  • RemoveResponseHeader:移除响应头
  • SetResponseHeader:设置响应头

4.Path:

  • PrefixPath:路径前缀
  • SetPath:设置替换路径
  • RedirectTo:重定向

配置文件:

spring:
  application:
    name: cloud-gateway
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    gateway:
      routes:
        - id: payment_route1
#          uri: http://localhost:9001
          uri: lb://nacos-pay-provider #动态路由,直接寻找微服务,支持负载均衡
          predicates:
            - Path=/pay/gateway/get/**
            - After=2025-02-05T15:08:30.031606300+08:00[Asia/Shanghai]
            - Cookie=username,zzyy
            - Header=X-Request-Id, \d+
            - Host=**.zzyy.com
            - Query=username, \d+
#            - RemoteAddr=192.168.83.1/24
            - Method=GET, POST
#            - name: My
#              args:
#                userType: diamond
            - My=diamond
        - id: payment_route2
#          uri: http://localhost:9001
          uri: lb://nacos-pay-provider
          predicates:
            - Path=/pay/gateway/info/**
        - id: payment_route3
            #          uri: http://localhost:9001
          uri: lb://nacos-pay-provider
          predicates:
            - Path=/pay/gateway/filter/**
#            - Path=/gateway/filter/**
#            - Path=/XYZ/abc/{segment}
          filters:
            - RedirectTo=302,http://www.baidu.com #302错误进行跳转
#            - SetPATH=/pay/gateway/{segment} # 上面配置的/XYZ/abc会被替换为当前路径
#            - PrefixPath= /pay # 前缀由配置统一管理
#            - AddRequestHeader=X-Request-yeffky,yeffky
#            - RemoveRequestHeader=cookie
#            - SetRequestHeader=X-Request-Id,123456
#            - AddRequestParameter=customerId,9527001
#            - RemoveRequestParameter=customerName
#            - AddResponseHeader=X-Response-Id,BlueResponse
#            - RemoveResponseHeader=Content-Type
#            - SetResponseHeader=Date,2099-11-11

7.8.4.自定义过滤器

  • 自定义全局Filter:统计接口调用耗时
@Component
@Slf4j
public class MyGlobalFilter implements GlobalFilter, Ordered {

    public static final String BEGIN_VISIT_TIME = "begin_visit_time";
    @Override
    public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        exchange.getAttributes().put(BEGIN_VISIT_TIME, System.currentTimeMillis());
        return chain.filter(exchange).then(Mono.fromRunnable(()->{
            Long beginVisitTime = exchange.getAttribute(BEGIN_VISIT_TIME);
            if (beginVisitTime != null) {
                log.info("访问接口主机:" + exchange.getRequest().getURI().getHost());
                log.info("访问接口端口:" + exchange.getRequest().getURI().getPort());
                log.info("访问接口URL:" + exchange.getRequest().getURI().getPath());
                log.info("访问接口参数:" + exchange.getRequest().getURI().getRawQuery());
                log.info("访问接口时长:" + (System.currentTimeMillis() - beginVisitTime) + "ms");
                log.info("=================");
                System.out.println();
            }
        }));
    }

//    数字越小,优先级越高
    @Override
    public int getOrder() {
        return 0;
    }
}
  • 自定义条件Filter
  • 配置类
@Component
public class MyGatewayFilterFactory extends AbstractGatewayFilterFactory {

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


    @Override
    public GatewayFilter apply(Config config) {
        return new GatewayFilter() {
            @Override
            public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                ServerHttpRequest request = exchange.getRequest();
                System.out.println("进入了自定义网关过滤器:" + config.getStatus());
                if (request.getQueryParams().containsKey(config.getStatus())) {
                    return chain.filter(exchange);
                } else {
                    exchange.getResponse().setStatusCode(HttpStatus.BAD_GATEWAY);
                    return exchange.getResponse().setComplete();
                }

            }
        };
    }

    public static class Config {
        @Getter @Setter
        private String status;
    }

    @Override
    public List shortcutFieldOrder() {
        return Arrays.asList("status");
    }
}

-yml配置

spring:
  cloud:
    gateway:
      routes:
        - id: payment_route3
            #          uri: http://localhost:9001
          uri: lb://nacos-pay-provider
          predicates:
            - Path=/pay/gateway/filter/**
          filters:
            - My=yeffky #需要有yeffky这个键,而非键值对为"status: yeffky"

相关推荐

墨尔本一华裔男子与亚裔男子分别失踪数日 警方寻人

中新网5月15日电据澳洲新快网报道,据澳大利亚维州警察局网站消息,22岁的华裔男子邓跃(Yue‘Peter’Deng,音译)失踪已6天,维州警方于当地时间13日发布寻人通告,寻求公众协助寻找邓跃。华...

网络交友须谨慎!美国犹他州一男子因涉嫌杀害女网友被捕

伊森·洪克斯克(图源网络,侵删)据美国广播公司(ABC)25日报道,美国犹他州一名男子于24日因涉嫌谋杀被捕。警方表示,这名男子主动告知警局,称其杀害了一名在网络交友软件上认识的25岁女子。雷顿警...

一课译词:来龙去脉(来龙去脉 的意思解释)

Mountainranges[Photo/SIPA]“来龙去脉”,汉语成语,本指山脉的走势和去向,现比喻一件事的前因后果(causeandeffectofanevent),可以翻译为“i...

高考重要考点:range(range高考用法)

range可以用作动词,也可以用作名词,含义特别多,在阅读理解中出现的频率很高,还经常作为完形填空的选项,而且在作文中使用是非常好的高级词汇。...

C++20 Ranges:现代范围操作(现代c++白皮书)

1.引言:C++20Ranges库简介C++20引入的Ranges库是C++标准库的重要更新,旨在提供更现代化、表达力更强的方式来处理数据序列(范围,range)。Ranges库基于...

学习VBA,报表做到飞 第二章 数组 2.4 Filter函数

第二章数组2.4Filter函数Filter函数功能与autofilter函数类似,它对一个一维数组进行筛选,返回一个从0开始的数组。...

VBA学习笔记:数组:数组相关函数—Split,Join

Split拆分字符串函数,语法Split(expression,字符,Limit,compare),第1参数为必写,后面3个参数都是可选项。Expression为需要拆分的数据,“字符”就是以哪个字...

VBA如何自定义序列,学会这些方法,让你工作更轻松

No.1在Excel中,自定义序列是一种快速填表机制,如何有效地利用这个方法,可以大大增加工作效率。通常在操作工作表的时候,可能会输入一些很有序的序列,如果一一录入就显得十分笨拙。Excel给出了一种...

Excel VBA入门教程1.3 数组基础(vba数组详解)

1.3数组使用数组和对象时,也要声明,这里说下数组的声明:'确定范围的数组,可以存储b-a+1个数,a、b为整数Dim数组名称(aTob)As数据类型Dimarr...

远程网络调试工具百宝箱-MobaXterm

MobaXterm是一个功能强大的远程网络工具百宝箱,它将所有重要的远程网络工具(SSH、Telnet、X11、RDP、VNC、FTP、MOSH、Serial等)和Unix命令(bash、ls、cat...

AREX:携程新一代自动化回归测试工具的设计与实现

一、背景随着携程机票BU业务规模的不断提高,业务系统日趋复杂,各种问题和挑战也随之而来。对于研发测试团队,面临着各种效能困境,包括业务复杂度高、数据构造工作量大、回归测试全量回归、沟通成本高、测试用例...

Windows、Android、IOS、Web自动化工具选择策略

Windows平台中应用UI自动化测试解决方案AutoIT是开源工具,该工具识别windows的标准控件效果不错,但是当它遇到应用中非标准控件定义的UI元素时往往就无能为力了,这个时候选择silkte...

python自动化工具:pywinauto(python快速上手 自动化)

简介Pywinauto是完全由Python构建的一个模块,可以用于自动化Windows上的GUI应用程序。同时,它支持鼠标、键盘操作,在元素控件树较复杂的界面,可以辅助我们完成自动化操作。我在...

时下最火的 Airtest 如何测试手机 APP?

引言Airtest是网易出品的一款基于图像识别的自动化测试工具,主要应用在手机APP和游戏的测试。一旦使用了这个工具进行APP的自动化,你就会发现自动化测试原来是如此简单!!连接手机要进行...

【推荐】7个最强Appium替代工具,移动App自动化测试必备!

在移动应用开发日益火爆的今天,自动化测试成为了确保应用质量和用户体验的关键环节。Appium作为一款广泛应用的移动应用自动化测试工具,为测试人员所熟知。然而,在不同的测试场景和需求下,还有许多其他优...

取消回复欢迎 发表评论: