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

SpringCloud学习笔记(四)

yuyutoo 2025-02-15 18:05 1 浏览 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"

相关推荐

史上最全的浏览器兼容性问题和解决方案

微信ID:WEB_wysj(点击关注)◎◎◎◎◎◎◎◎◎一┳═┻︻▄(页底留言开放,欢迎来吐槽)●●●...

平面设计基础知识_平面设计基础知识实验收获与总结
平面设计基础知识_平面设计基础知识实验收获与总结

CSS构造颜色,背景与图像1.使用span更好的控制文本中局部区域的文本:文本;2.使用display属性提供区块转变:display:inline(是内联的...

2025-02-21 16:01 yuyutoo

写作排版简单三步就行-工具篇_作文排版模板

和我们工作中日常word排版内部交流不同,这篇教程介绍的写作排版主要是用于“微信公众号、头条号”网络展示。写作展现的是我的思考,排版是让写作在网格上更好地展现。在写作上花费时间是有累积复利优势的,在排...

写一个2048的游戏_2048小游戏功能实现

1.创建HTML文件1.打开一个文本编辑器,例如Notepad++、SublimeText、VisualStudioCode等。2.将以下HTML代码复制并粘贴到文本编辑器中:html...

今天你穿“短袖”了吗?青岛最高23℃!接下来几天气温更刺激……

  最近的天气暖和得让很多小伙伴们喊“热”!!!  昨天的气温到底升得有多高呢?你家有没有榜上有名?...

CSS不规则卡片,纯CSS制作优惠券样式,CSS实现锯齿样式

之前也有写过CSS优惠券样式《CSS3径向渐变实现优惠券波浪造型》,这次再来温习一遍,并且将更为详细的讲解,从布局到具体样式说明,最后定义CSS变量,自定义主题颜色。布局...

柠檬科技肖勃飞:大数据风控助力信用社会建设

...

你的自我界限够强大吗?_你的自我界限够强大吗英文

我的结果:A、该设立新的界限...

行内元素与块级元素,以及区别_行内元素和块级元素有什么区别?

行内元素与块级元素首先,CSS规范规定,每个元素都有display属性,确定该元素的类型,每个元素都有默认的display值,分别为块级(block)、行内(inline)。块级元素:(以下列举比较常...

让“成都速度”跑得潇潇洒洒,地上地下共享轨交繁华
让“成都速度”跑得潇潇洒洒,地上地下共享轨交繁华

去年的两会期间,习近平总书记在参加人大会议四川代表团审议时,对治蜀兴川提出了明确要求,指明了前行方向,并带来了“祝四川人民的生活越来越安逸”的美好祝福。又是一年...

2025-02-21 16:00 yuyutoo

今年国家综合性消防救援队伍计划招录消防员15000名

记者24日从应急管理部获悉,国家综合性消防救援队伍2023年消防员招录工作已正式启动。今年共计划招录消防员15000名,其中高校应届毕业生5000名、退役士兵5000名、社会青年5000名。本次招录的...

一起盘点最新 Chrome v133 的5大主流特性 ?

1.CSS的高级attr()方法CSSattr()函数是CSSLevel5中用于检索DOM元素的属性值并将其用于CSS属性值,类似于var()函数替换自定义属性值的方式。...

竞走团体世锦赛5月太仓举行 世界冠军杨家玉担任形象大使

style="text-align:center;"data-mce-style="text-align:...

学物理能做什么?_学物理能做什么 卢昌海

作者:曹则贤中国科学院物理研究所原标题:《物理学:ASourceofPowerforMan》在2006年中央电视台《对话》栏目的某期节目中,主持人问过我一个的问题:“学物理的人,如果日后不...

你不知道的关于这只眯眼兔的6个小秘密
你不知道的关于这只眯眼兔的6个小秘密

在你们忙着给熊本君做表情包的时候,要知道,最先在网络上引起轰动的可是这只脸上只有两条缝的兔子——兔斯基。今年,它更是迎来了自己的10岁生日。①关于德艺双馨“老艺...

2025-02-21 16:00 yuyutoo

取消回复欢迎 发表评论: