gateway网关的使用

news2024/11/18 3:28:54

今天与大家分享gateway网关的使用

1. gateway简介

1.1 是什么

SpringCloud Gateway 作为 Spring Cloud 生态系统中的网关,目标是替代 Zuul,在Spring Cloud 2.0以上版本中,没有对新版本的Zuul 2.0以上最新高性能版本进行集成,仍然还是使用的Zuul 2.0之前的非Reactor模式的老版本。而为了提升网关的性能,SpringCloud Gateway是基于WebFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactor模式通信框架Netty。

1.2 作用

Spring Cloud Gateway 的目标,不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控/指标,和限流。

1.3 主要特征

  • 基于 Spring Framework 5,Project Reactor 和 Spring Boot 2.0
  • 集成 Hystrix 断路器
  • 集成 Spring Cloud DiscoveryClient
  • Predicates 和 Filters 作用于特定路由,易于编写的 Predicates 和 Filters
  • 具备一些网关的高级功能:动态路由、限流、路径重写

1.4 与zuul的主要区别

Spring Cloud Gateway 底层使用了高性能的通信框架Netty, zuul采用的是传统的servlet IO。

1.5 主要组件

  • Filter
    过滤器,与zuul中的过滤器作用相同,可以用来拦截和修改请求,也可以对响应做处理。比如用来进行安全校验等。

  • Route
    路由组件,将网关接受到的请求发送给指定的上游服务进行处理。一个Route模块由一个 ID,一个目标 URI,一组断言和一组过滤器定义。如果断言为真,则路由匹配,目标URI会被访问

  • Predicate
    断言, 这是一个 Java 8 的 Predicate。简单的理解是路由转发的条件,满足条件的请求才会被转发。有点像sql中的where子句的作用。

1.6 架构图

官网icon-default.png?t=MBR7https://docs.spring.io/spring-cloud-gateway/docs/2.2.5.RELEASE/reference/html/

 

对上图的理解:
客户端向 Spring Cloud Gateway 发出请求。然后在 Gateway Handler Mapping 中找到与请求相匹配的路由,将其发送到 Gateway Web Handler。Handler 再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回。过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前(“pre”)或之后(“post”)执行业务逻辑

2. 开发示例

2.1 创建一个gateway模块

1)创建一个gateway模块

 

2)如上图,配置pom文件,引入必要的包

    <dependencies>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

        <!-- 从注册中心进行服务发现 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <!-- 向注册中心进行服务注册 -->
        <dependency>
            <groupId>com.alibaba.nacos</groupId>
            <artifactId>nacos-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

    </dependencies>
  1. 项目配置文件:application.yml

 

server:
  port: 8090

spring:
  application:
    name: service-gateway
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848

4)创建启动类

 

@SpringBootApplication
public class GatewayApp {

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

}

2.2 与nacos结合使用

2.2.1 默认规则

将gateway注册到nacos注册中心,使用默认规则进行路由,默认规则使用简单,但功能也相当较弱。
默认规则:
http://gateway_host:gateway_port/服务名/**

服务名 默认为nacos注册的服务点的大写,可以修改

配置文件:

server:
  port: 8090

spring:
  application:
    name: service-gateway
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848

    gateway:
      discovery:
        locator:
          #开启服务发现功能,从注册中心获取服务列表,(nacos->服务管理->服务列表)
          #默认服务名称需要为大写,可以通过配置lower-case-service-id: true 改变这一规则
          enabled: true
          #配置服务名使用小写
          lower-case-service-id: true

#配置配置
logging:
  level:
    #trace,debug,info
    org.pringframework.cloud.gateway: trace #便于跟踪调试,生产环境最好不用
    org.springframework.http.server.reactive: debug
    org.springframework.web.reactive: debug
    reactor.ipc.netty: debug

2.2.2 通过配置文件配置路由

RouteDefinition中,主要有五个属性:

  • id:路由标识(id:标识,具有唯一性,默认为uuid
  • predicates:PredicateDefinition 路由断言定义列表
  • filters:FilterDefinition 过滤器定义列表,为一个数组
  • uri:目标服务地址(uri:地址,请求转发后的地址)
  • order:优先级, 越小越优先

通过配置文件配置路由的缺点是,当增加服务时需要修改配置文件并重启网关。

配置文件:

server:
  port: 8090

spring:
  application:
    name: service-gateway
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848

    gateway:
      discovery:
        locator:
          #开启服务发现功能,从注册中心获取服务列表,(nacos->服务管理->服务列表)
          #默认服务名称需要为大写,可以通过配置lower-case-service-id: true 改变这一规则
          enabled: false
          #配置服务名使用小写
          lower-case-service-id: true

      routes:
        # http://localhost:5000/usr/hello
        #路由标识(id:标识,具有唯一性)
        - id: consumer-service-api
          #目标服务地址(uri:地址,请求转发后的地址),会自动从注册中心获得服务的IP,不需要手动写死
          uri: lb://service-consumer
          #优先级,越小越优先
          #order: 999
          #路由条件(predicates:断言)
          predicates:
          # 路径匹配,
          - Path=/consumer/**
          filters:
          #路径前缀删除示例:请求/name/bar/foo,StripPrefix=2,去除掉前面两个前缀之后,最后转发到目标服务的路径为/foo
          #前缀过滤,请求地址:http://localhost:5000/usr/hello
          #此处配置去掉1个路径前缀,再配置上面的 Path=/usr/**,就将**转发到指定的微服务
          #因为这个api相当于是服务名,只是为了方便以后nginx的代码加上去的,对于服务提供者service-client来说,不需要这段地址,所以需要去掉
          - StripPrefix=1

#配置配置
logging:
  level:
    #trace,debug,info
    org.pringframework.cloud.gateway: trace #便于跟踪调试,生产环境最好不用
    org.springframework.http.server.reactive: debug
    org.springframework.web.reactive: debug
    reactor.ipc.netty: debug

2.2.3 动态路由

功能强,在新增服务时不需要重启网关

1)配置文件

 

# 自定义配置
# 自定义配置
nacos:
  dataId: gateway-config.json
  group: GWC-GROUP

#配置配置
logging:
  level:
    #trace,debug,info
    #便于跟踪调试,生产环境最好不用
    org.springframework.cloud.gateway: trace
    org.springframework.http.server.reactive: debug
    org.springframework.web.reactive: debug
    reactor.ipc.netty: debug

2)读取配置文件的中的配置信息

/**
 * 1. 保存Gateway(网关)中与nacos相关的属性
 * 2. 这些信息是自定义配置属性,它们保存在配置文件application.yml中
 */
@Configuration
@Data
public class GatewayNacosProperties {

    @Value("${spring.cloud.nacos.discovery.server-addr}")
    private String serverAddr;

    @Value("${nacos.dataId}")
    private String dataId;

    @Value("${nacos.group}")
    private String group;

}

3)实现实现动态路由

/**
 * 此类实现了Spring Cloud Gateway + nacos 的动态路由
 * 该类用于监听配置中心中的路由配置的变化,当监听到配置变化,则发布一个事件,
 * 用于更新本地路由信息。
 * 它实现一个Spring提供的事件推送接口ApplicationEventPublisherAware
 */
@Component
public class DynamicRoutingConfig implements ApplicationEventPublisherAware {

    private final Logger logger = LoggerFactory.getLogger(DynamicRoutingConfig.class);

    @Autowired
    private RouteDefinitionWriter routeDefinitionWriter;

    @Autowired
    private GatewayNacosProperties gatewayNacosProperties;

    private ApplicationEventPublisher applicationEventPublisher;


    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }

    /**
     * 这个方法主要负责监听Nacos的配置变化,这里先使用参数构建一个ConfigService,再使用ConfigService开启一个监听,
     * 并且在监听的方法中刷新路由信息。
     *
     * @throws NacosException
     */
    @Bean
    public void refreshRouting() throws NacosException {
        Properties properties = new Properties();
        properties.put(PropertyKeyConst.SERVER_ADDR, gatewayNacosProperties.getServerAddr());
        ConfigService configService = NacosFactory.createConfigService(properties);

        //获得nacos中已有的路由配置
        String json = configService.getConfig(gatewayNacosProperties.getDataId(), gatewayNacosProperties.getGroup(), 8090);
        this.parseJson(json);

        //添加监听器,监听nacos中的数据修改事件
        configService.addListener(gatewayNacosProperties.getDataId(), gatewayNacosProperties.getGroup(), new Listener() {
            @Override
            public Executor getExecutor() {
                return null;
            }

            @Override
            public void receiveConfigInfo(String configInfo) {
                logger.info(configInfo);
                parseJson(configInfo);
            }
        });
    }


    /**
     * 解析从nacos读取的路由配置信息(json格式)
     *
     * @param json
     */
    public void parseJson(String json) {
        logger.info("从Nacos返回的路由配置(JSON格式):" + json);
        List<RouteDefinition> routeArr = JSON.parseArray(json).toJavaList(RouteDefinition.class);
        for (RouteDefinition route : routeArr) {
            update(route);
        }
    }


    /**
     * 路由更新:
     * 1)先将原来的路由信息删除
     * 2)保存新的路由信息
     * @param routeDefinition
     * @return
     */
    public void update(RouteDefinition routeDefinition) {

        try {
            this.routeDefinitionWriter.delete(Mono.just(routeDefinition.getId()));
            logger.info("删除原来的路由信息");
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }

        try {
            routeDefinitionWriter.save(Mono.just(routeDefinition)).subscribe();
            this.applicationEventPublisher.publishEvent(new RefreshRoutesEvent(this));
            logger.info("路由更新成功");
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
    }

}

4)在配置中心中配置路由信息

 

路由配置采用json格式,参考配置如下:

[
  {
    "id": "service-consumer",
    "predicates": [
      {
        "name": "Path",
        "args": {
        "_genkey_0": "/consumer/**"
        }
      }
    ],
    "filters": [
      {
        "name": "StripPrefix",
        "args": {
          "_genkey_0": "1"
        }
      }
    ],
    "uri": "lb://service-consumer",
    "order": 0
  }
]

需要根据自己的项目的具体情况配置。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/148441.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java设计模式中外观模式是什么/外观模式有什么用,如何实现

继续整理记录这段时间来的收获&#xff0c;详细代码可在我的Gitee仓库SpringBoot克隆下载学习使用&#xff01; 5.6 外观模式 5.6.1 概述 又称门面模式&#xff0c;通过为多个子系统提供一个一致接口&#xff0c;而使这些子系统更加容易被访问的模式对外有一个统一接口&…

SAP工作流规则

代理人规则获取部分&#xff0c;灵活工作流和传统工作流一致 1. 事务代码&#xff1a;PFAC&#xff0c;用来创建规则 2. 规则用来确定代理&#xff0c;可通过如下下拉框中多种方式确定代理人 责任可在事务代码OOCU_RESP中配置代理人&#xff0c;可用来代替配置表确定代理人的…

Python蓝桥杯训练:数组和字符串 Ⅴ

Python蓝桥杯训练&#xff1a;数组和字符串 Ⅴ 文章目录Python蓝桥杯训练&#xff1a;数组和字符串 Ⅴ一、找到数组的中间位置二、使用最小花费爬楼梯一、找到数组的中间位置 给你一个下标从 0 开始的整数数组 nums &#xff0c;请你找到 最左边 的中间位置 middleIndex &#…

推荐系统实战5——EasyRec 在DSSM召回模型中添加负采样构建CTR点击平台

推荐系统实战5——EasyRec 在DSSM召回模型中添加负采样构建CTR点击平台学习前言EasyRec仓库地址DSSM实现思路一、DSSM整体结构解析二、网络结构解析1、Embedding层的构建2、网络层的构建3、相似度计算三、训练部分解析训练自己的DSSM模型一、数据集的准备二、Config配置文件的设…

一键生成分享链接的贺卡制作工具

不用自己动手设计&#xff0c;在线模板帮你轻松搞定新春贺卡设计&#xff0c;免下载的设计工具。跟着小编的设计教程&#xff0c;教你如何使用乔拓云工具&#xff0c;在线搞定你的新春祝福贺卡设计&#xff0c;不用任何设计经验&#xff0c;只需要跟着教程就能搞定的专属贺卡设…

论文笔记:RCLane: Relay Chain Prediction for Lane Detection

RCLane: Relay Chain Prediction for Lane Detection笔记摘要动机模型结构方法其他模型试验结果笔记摘要 该篇论文的核心创新点在于head。论文根据车道线既需要局部信息&#xff0c;也需要全局信息才能很好拟合的特性&#xff0c;设计了相应的算法head。并且论文实验证明该方法…

机器视觉(十一):条码识别

目录&#xff1a; 机器视觉&#xff08;一&#xff09;&#xff1a;概述 机器视觉&#xff08;二&#xff09;&#xff1a;机器视觉硬件技术 机器视觉&#xff08;三&#xff09;&#xff1a;摄像机标定技术 机器视觉&#xff08;四&#xff09;&#xff1a;空域图像增强 …

记一次虚拟机编译c程序错误

file included from /usr/include/stdio.h:74:0, from opendir.c:2: /usr/include/libio.h:302:3: error: unknown type name ‘size_t’ size_t __pad5; ^ /usr/include/libio.h:305:67: error: ‘size_t’ undeclared here (not in a function) ch…

黑马程序员 Maven 教程

Maven 简介 传统项目管理的缺点&#xff1a; (1) jar 包不统一&#xff0c;jar 包不兼容; (2) 工程升级维护过程操作繁琐; Maven 是什么 Maven 的本质是一个项目管理工具&#xff0c;将项目开发和管理过程抽象成一个项目对象模型 (POM) POM (Project Object Model) : 项目对…

二分搜索算法

目录1.概述2.代码实现2.1.最基本的二分搜索2.2.搜索最左侧边界2.3.搜索最右侧边界3.应用本文参考&#xff1a; LABULADONG 的算法网站 《大话数据结构》 1.概述 &#xff08;1&#xff09;二分搜索 (Binary Search)&#xff0c;又称为折半搜索 (Half-interval Search)。它的前…

云收藏系统|基于Springboot实现云收藏系统

作者主页&#xff1a;编程指南针 作者简介&#xff1a;Java领域优质创作者、CSDN博客专家 、掘金特邀作者、多年架构师设计经验、腾讯课堂常驻讲师 主要内容&#xff1a;Java项目、毕业设计、简历模板、学习资料、面试题库、技术互助 收藏点赞不迷路 关注作者有好处 文末获取源…

Java实现队列

目录 一、队列概述 二、队列的模拟实现 1、入队 2、出队 3、取队头元素 4、获取队列长度 三、循环队列 1、入队 2、出队 3、取队头元素 4、取队尾元素 四、面试题 1、用队列实现栈 2、用栈实现队列 一、队列概述 队列也是常见的数据结构&#xff0c;是一…

Mybatis源码解析二:DataSource数据源负责创建连接以及Transaction的事物管理

简介 对于一个成熟的ORM框架来说&#xff0c;数据源的管理以及事务的管理一定是不可或缺的组成&#xff0c;对于Mybatis来说&#xff0c;为了使用方便以及扩展简单也是做了一系列的封装&#xff0c;这一篇主要介绍mybatis是如何管理数据源以及事务的。 数据源DataSource Dat…

【深度学习】李宏毅2021/2022春深度学习课程笔记 - Adversarial Attack(恶意攻击)

文章目录一、基本概念1.1 动机1.2 恶意攻击的例子1.3 如何攻击&#xff1f;二、White Box vs Black Box三、One Pixel Attack四、Universal Adversarial Attack五、Beyond Image六、Attack in the Physical World七、Adversarial Reprogramming八、Backdoor in Model九、防御9.…

TLS回调函数实现反调试

title: TLS回调函数实现反调试.md date: 2022-06-16 23:40:49.231 updated: 2022-06-16 23:41:11.924 url: /archives/tls回调函数实现反调试 categories: tags: 逆向 TLS回调函数实现反调试 TLS-线程局部存储 先于我们OEP执行 #include<stdlib.h> #include<time.…

使用红黑树封装map、set

map、set如何用红黑树封装 map、set应用&#xff1a;map是一个使用参数K、参数V的类模板&#xff0c;set是只使用参数K的类模板。因为map应用时&#xff0c;需要使用到KV&#xff0c;而set只是存单个值&#xff0c;K。红黑树类的存储 &#xff1a;map和set类中使用红黑树数据成…

Logback配置详解

简介&#xff1a; logback是java的日志开源组件&#xff0c;是log4j创始人写的&#xff0c;性能比log4j要好&#xff0c;目前主要分为3个模块&#xff1a; logback-core:核心代码模块logback-classic:log4j的一个改良版本&#xff0c;同时实现了slf4j的接口&#xff0c;这样你…

树莓派mjpg-streamer实现监控功能

树莓派实现监控功能&#xff0c;调用mjpg-streamer库来实现。mjpg-streamer是一个开源的摄像头媒体流&#xff0c;通过本地获取摄像头的数据&#xff0c;通过http通讯发送&#xff0c;可以通过浏览器访问树莓派的IP地址和端口号就能看到视频流。 实现步骤 1.git clone https:…

关于内核的概念理解

狭义的操作系统可以认为就是内核&#xff0c;比如Linux内核。广义的操作系统则包括内核和一系列应用软件&#xff0c;比如Linux内核编辑器vim编译器gcc命令行解释器&#xff08;shell&#xff09;等&#xff0c;通常称为GNU/Linux。 源代码https://github.com/torvalds/Linux …

Jenkins自动化部署SpringBoot项目(windows环境)

文章目录1、Jenkins介绍1.1、概念1.2、优势1.3、Jenkins目的2、环境准备3、Jenkins下载3.1、下载3.2、运行3.3、问题解决4、Jenkins配置4.1、用户配置4.2、系统配置4.3、全局工具配置-最重要5、新建项目7、测试8、错误解决1、Jenkins介绍 1.1、概念 Jenkins是一个开源软件项目…