SpringCloud Gateway网关的使用与介绍

news2024/11/16 13:49:28

目录

1. gateway简介

1.1 是什么

1.2 作用

1.3 主要特征

1.4 与zuul的主要区别

1.5 主要组件

1.6 架构图

2. 开发示例

2.1 创建一个gateway模块

2.2 与nacos结合使用

2.2.1 默认规则

2.2.2 通过配置文件配置路由

2.2.3 动态路由


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 架构图

官网

对上图的理解:

客户端向 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.projectlombok</groupId>
         <artifactId>lombok</artifactId>
         <version>1.18.22</version>
         <scope>provided</scope>
        </dependency>
        <dependency>
         <groupId>com.alibaba</groupId>
         <artifactId>fastjson</artifactId>
         <version>1.2.73</version>
       </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
@EnableDiscoveryClient
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

测试 比如我有一个模块注册名为service-consumer 那么请求为http://localhost:8090/service-consumer/***(设置项目的请求路径)

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

- Path=/consumer/** 这个参数中间为断言可理解为别名

- StripPrefix=1 //在真实拼接地址的时候 跳过consumer这一段 如果断言为- Path=/consumer/dd/** 那么下方参数就需要进行更改 要跳过两段- StripPrefix=2 //跳过 的为 consumer/dd

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格式,参考配置如下: service-consumer 服务名称 本地配置中的名称

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

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

配置两个模块

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

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

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

相关文章

Vulnhub靶机:PRIME_ 1

目录介绍信息收集主机信息探测主机信息探测网站探测目录爆破排雷dirsearch强制访问文件包含漏洞利用WordPress提权wordpress配置文件内核提权介绍 系列&#xff1a;Prime&#xff08;此系列共1台&#xff09; 发布日期&#xff1a;2019年9月1日 难度&#xff1a;初-中 运行环境…

在 Istio 服务网格中使用 Argo Rollouts 实现智能的渐进式发布

1 Argo Rollouts 介绍 Kubernetes 原生的 Deployment 利用 Rolling Update 滚动更新的策略在应用升级时提供基本的安全保证&#xff08;例如就绪探针&#xff09;。然而默认的滚动更新策略存在着一些明显的缺点&#xff0c;例如&#xff1a; 无法控制流向新版本的流量。无法控…

tensorflow入门(四)如何用tensorflow训练神经网络

参考 如何用tensorflow训练神经网络 - 云社区 - 腾讯云 在使用神经网络解决实际的分类或回归问题时需要设置好参数取值。下面介绍使用监督学习的方式来合理地设置参数取值&#xff0c;同时也将给出tensorflow程序来完成这个过程。设置神经网络参数的过程就是神经网络的训练过…

基于JDBC的MySQL数据库编程

✨博客主页: 荣 ✨系列专栏: MySQL ✨一句短话: 难在坚持,贵在坚持,成在坚持! 文章目录一. JDBC概述二. JDBC前置工作1. 准备好MySQL驱动包2. 创建项目三. JDBC的使用步骤1. 创建数据源DataSourece2. 连接数据库3. 构造并执行sql语句4. 释放资源5. sql语句不要写死(以插入为例)…

C++入门基础07:函数定义与声明、函数传参(传值、传地址、传引用)、函数重载

C入门基础07&#xff1a;函数定义与声明、函数传参&#xff08;传值、传地址、传引用&#xff09;、函数重载 1、函数定义与声明 函数是一起执行一个任务的一组语句。每个程序&#xff08;C/C&#xff09;都有一个主函数 main() &#xff0c; 所有简单的程序都可以定义其他额…

1563_AURIX_TC275_EVR的控制寄存器

全部学习汇总&#xff1a; GreyZhang/g_TC275: happy hacking for TC275! (github.com) 1. 连续的写入必须确保是解锁状态&#xff0c;否则的话可能会导致所有的总线阻塞。 2. 多核系统中&#xff0c;尽量写入之后再读取一下确认写入的状态。 这里是过压以及欠压的几个监控结果…

if、for、while结构的用法

分支与循环的流程控制一、分支流程控制1. if分支语句结构1). 单分支2). 双分支3). 三元运算符&#xff08;双分支的简化&#xff09;4). 多分支二. 循环流程控制1. while循环语句语法结构1.while循环用法2.while 的死循环3. while else的用法2. for循环语句语法结构1. for和ran…

嵌入式开发学习之--串口通讯(上)

提示&#xff1a;本篇开始学习各种通讯方式&#xff0c;重中之重。 文章目录前言一、 串口通讯协议简介1.1 物理层1.2 协议层1.2.1 基本组成。1.2.2 波特率1.2.3 起始和终止位1.2.4 有效数据1.2.5 数据校验二、USART结构体详解总结前言 作为一个嵌入式的开发者&#xff0c;解析…

网页木马挂马的实现与防范

一、网页挂马是什么 不少用户都碰到过这样的现象&#xff1a;打开一个网站&#xff0c;结果页面还没显示&#xff0c;杀毒软件就开始报警&#xff0c;提示检测到木马病毒。有经验的朋友会知道这是网页恶意代码&#xff0c;这就是典型的网页挂马现象。那么是什么原因导致了这种…

数据库概论之MySQL表的增删改查 - 进阶版本1

MySQL表的增删改查 - 进阶1、数据库约束1.1 约束类型1.2 NULL约束1.3 UNIQUE约束1.4 DEFAULT约束1.5 PRIMARY约束1.6 FOREIGN KEY外键约束1.6.1 语法1.6.2 工作原理2、表的设计2.1 一对一2.2 一对多2.3 多对多大家好&#xff0c;已经好久没更新了 , 学校的学业有点忙 , 没有额外…

[论文解析] Denoising Diffusion Probabilistic Models

文章目录OverviewsWhat problem is addressed in the paper?What is the key to the solution?What is the main contribution?Contents扩散概率模型背景算法实验结论Overviews What problem is addressed in the paper? We present high quality image synthesis result…

【Java面试】说说类加载机制(流程)

文章目录加载流程装载(Load)链接(Link)验证(Verify)准备(Prepare)解析(Resolve)初始化(Initialize)卸载(Unload)加载流程 类的加载流程如下&#xff1a; 转载(Load)->链接(Link)->初始化(Initialize)->使用(Use)->卸载(Unload) 其中链接又包含验证(Verify)&#x…

rabbitMQ延时队列——TTL和DLX

一. 场景&#xff1a;“订单下单成功后&#xff0c;15分钟未支付自动取消” 1.传统处理超时订单 采取定时任务轮训数据库订单&#xff0c;并且批量处理。其弊端也是显而易见的&#xff1b;对服务器、数据库性会有很大的要求&#xff0c; 并且当处理大量订单起来会很力不从…

flask前后端项目--实例-前端部分:-4-vue-Element Plus

flask前后端项目--实例-前端部分&#xff1a;-4-vue-Element Plus组件添加事项 一、实验测试步骤 1.Element Plus添加 1.先备份App.VUE&#xff0c;然后修改app.vue的内容&#xff0c;数据来源资Element Plus的表格table 2. 数据来源资Element Plus的表格table 3. 运行服务&…

023_SSS_Neural 3D Video Synthesis from Multi-view Video(CVPR2022)

Neural 3D Video Synthesis from Multi-view Video(CVPR2022) 本文提出了一种新的3D视频生成方法&#xff0c;这种方法能够以紧凑但富有表现力的表示形式表示动态真实世界场景的多视图视频记录&#xff0c;从而实现高质量的视图合成和运动插值。 1. Introduction 本文的主要…

百度地图 ( 一 ) 显示地图

1.百度地图 百度地图开放平台 https://lbsyun.baidu.com/ 使用百度地图时导入JavaScript包 <script type"text/javascript" src"http://api.map.baidu.com/api?v2.0&ak您的密钥"></script>1.1.如何申请 ak 密钥 在 开发平台 找 控制…

ChatGPT注册流程

1.访问官网点击 Sign up https://chat.openai.com/auth/login 2.输入你的邮箱 3.点击Continue下一步: 4.输入密码继续下一步&#xff1a; 5.然后你的邮箱会受到一封邮件&#xff08;如果没收到请检查垃圾邮箱&#xff09;&#xff1a; 6.点击验证邮箱按钮&#xff0c;会跳到…

MySQL 5.7中文乱码与远程链接问题

MySQL 5.7中文乱码与远程链接问题1. MySQL 5.7中文乱码2. 远程链接问题3. 不区分表大小写4. 超过最大连接数5. 时区问题5. GROUP BY 问题配置集合重启MySQL1. MySQL 5.7中文乱码 当我们直接在数据库里面输入中文时&#xff0c;保存后出现&#xff1a; Incorrect string value&…

LeetCode 第 244 场周赛题解

前言 这是 2021-06-06 的一场 LeetCode 周赛&#xff0c;本场周赛的题目相较而以往而言比较简单&#xff0c;基本上想到点上就可以做出来&#xff0c;主要涉及到矩阵的旋转、贪心、滑动窗口、前缀和、二分查找等知识点。 第 244 场周赛链接&#xff1a;https://leetcode-cn.c…

SpringBoot+Vue实现前后端分离的学校快递站点管理系统

文末获取源码 开发语言&#xff1a;Java 使用框架&#xff1a;spring boot 前端技术&#xff1a;JavaScript、Vue.js 、css3 开发工具&#xff1a;IDEA/MyEclipse/Eclipse、Visual Studio Code 数据库&#xff1a;MySQL 5.7/8.0 数据库管理工具&#xff1a;phpstudy/Navicat JD…