返回顶部
首页 > 资讯 > 精选 >SpringCloud Gateway动态转发后端服务如何实现
  • 442
分享到

SpringCloud Gateway动态转发后端服务如何实现

2023-07-05 17:07:30 442人浏览 八月长安
摘要

今天小编给大家分享一下SpringCloud Gateway动态转发后端服务如何实现的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一

今天小编给大家分享一下SpringCloud Gateway动态转发后端服务如何实现的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

一、概述

通过把springCloudGateway的相关路由配置规则保存到数据库中,可以动态的灵活调整路由。在本文的实现中,我们通过请求header中的特定值,动态选择对应的后端服务地址。

二、项目中加入依赖

在项目的gradle中增加依赖关系。

build.gradle:

plugins {
    id 'org.springframework.boot' version '3.0.2'
    id 'io.spring.dependency-management' version '1.1.0'
    id 'java'
}

group = 'cn.sprinGCamp'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
    testCompileOnly {
        extendsFrom testAnnotationProcessor
    }
}

repositories {
    MavenCentral()
}

dependencies {
    implementation "org.springframework.boot:spring-boot-starter-JSON"
    implementation 'org.springframework.boot:spring-boot-starter-validation'
    implementation 'org.springframework.boot:spring-boot-starter-data-r2dbc'
    implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
    runtimeOnly 'com.h3Database:h3'
    runtimeOnly 'io.r2dbc:r2dbc-h3'
    annotationProcessor 'org.projectlombok:lombok'
    testAnnotationProcessor 'org.projectlombok:lombok'
    testImplementation "org.springframework.boot:spring-boot-starter-test"
    testImplementation 'org.junit.vintage:junit-vintage-engine'
    testImplementation 'io.projectReactor:reactor-test'
    testImplementation 'com.h3database:h3'
    testImplementation 'io.r2dbc:r2dbc-h3'
    testImplementation 'org.junit.vintage:junit-vintage-engine'
}

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:2022.0.1"
    }
}

test {
    useJUnitPlatfORM()
}

由于SpringCloudGateway基于SpringWEBFlux技术构建,所以依赖中的数据库配置需要使用r2dbc 。

三、配置文件

示例程序首选通过配置文件对路由进行基本配置,配置文件代码:

spring:
  r2dbc:
    url: r2dbc:h3:mem:///testdb?options=DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
    username: sa
    passWord:
  cloud:
    gateway:
      routes:
        - id: routeOne
          predicates:
            - Path=/route1/**
          uri: no://op
          filters:
            - UriHostPlaceholderFilter=10001
        - id: routeTwo
          predicates:
            - Path=/route2/**
          uri: no://op
          filters:
            - UriHostPlaceholderFilter=10001

配置文件中配置了2个路由,对应的接口地址路径分别是 /route1/**Path=/route2/**,路径中的 ***表示模糊匹配,只要是以 /route1/为前缀的路径都可以被访问到。

后端服务地址配置了一个无意的地址: uri: no://op,因为我们的处理逻辑会通过从数据库中读取配置来动态替换后端服务地址。

四、动态路由数据存储格式

我们通过 ROUTE_FILTER_ENTITY这个数据库表来存储接口后端服务配置数据。表结构为:

CREATE TABLE "ROUTE_FILTER_ENTITY"(   id VARCHAR(255) PRIMARY KEY,   route_id VARCHAR(255),  -- 路由ID,对应配置文件中的 ```id```配置项   code VARCHAR(255), -- 接口请求header中的code参数的值   url VARCHAR(255) -- 后端服务地址);

当客户端访问 /route1/test接口时,根据配置文件的路由配置,SpringCloudGateway 会命中 id: routeOne这个路由规则,这个规则对应的后端服务地址是 uri: no://op,并不是我们期望的真实后端服务地址。

因此,我们需要读取到真实的后端服务地址,并将请求转发到这个地址。跟据 routeId 和 接口请求header中的code参数的值,就可以从 ROUTE_FILTER_ENTITY 表中查到对应的后端服务地址 url这个字段的值。

我们已经读取到了后端服务地址,还需要将请求转发到这个地址,下面介绍转发的方法。

五、后端服务动态转发

动态转发通过自定义 filter 的方式实现,自定义 filter 代码如下:

@Componentpublic class UriHostPlaceholderFilter extends AbstractGatewayFilterFactory<UriHostPlaceholderFilter.Config> {    @Autowired    private RouteFilterRepository routeFilterRepository;    public UriHostPlaceholderFilter() {        super(Config.class);    }    @Override    public List<String> shortcutFieldOrder() {        return Collections.singletonList("order");    }    @Override    public GatewayFilter apply(Config config) {        return new OrderedGatewayFilter((exchange, chain) -> {            String code = exchange.getRequest().getHeaders().getOrDefault("code", new ArrayList<>()).stream().findFirst().orElse("");            String routeId = exchange.getAttribute(GATEWAY_PREDICATE_MATCHED_PATH_ROUTE_ID_ATTR);            if (StringUtils.hasText(code)) {                String newurl;                try {                    newurl = routeFilterRepository.findByRouteIdAndCode(routeId, code).toFuture().get().getUrl();                } catch (InterruptedException | ExecutionException e) {                    throw new RuntimeException(e);                }                if (StringUtils.hasText(exchange.getRequest().getURI().getQuery())) {                    newurl = newurl + "?" + exchange.getRequest().getURI().getQuery();                }                URI newUri = null;                try {                    newUri = new URI(newurl);                } catch (URISyntaxException e) {                    log.error("uri error", e);                }                exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, newUri);            }            return chain.filter(exchange);        }, config.getOrder());    }    @Data    @NoArgsConstructor    public static class Config {        private int order;        public Config(int order) {            this.order = order;        }    }}

通过扩展 AbstractGatewayFilterFactory 类,我们自定义了 UriHostPlaceholderFilter 这个 filter 。

代码的核心逻辑在 apply 方法中。

首先通过 String code = exchange.getRequest().getHeaders().getOrDefault("code", new ArrayList<>()).stream().findFirst().orElse("")可以获取到接口请求 header 中 code 这个参数的值。

再通过 String routeId = exchange.getAttribute(GATEWAY_PREDICATE_MATCHED_PATH_ROUTE_ID_ATTR)可以获取到 routeId 。

最后通过 newurl = routeFilterRepository.findByRouteIdAndCode(routeId, code).toFuture().get().getUrl()就可以从数据库中读取到配置好的后端服务地址。

拿到后端服务地址后, 通过调用 exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, newUri);将请求转发到对应的地址。

六、单元测试

在单元测试代码中,我们预置了一条后端服务动态配置数据:

insert into ROUTE_FILTER_ENTITY values('1','routeOne','alpha','Http://httpbin.org/anything')

然后模拟请求 /route1/test?a=test这个接口,根据我们的配置,请求会被转发到 http://httpbin.org/anything

执行单元测试后,可以从日志中发现,接口返回的数据是 http://httpbin.org/anything 这个后端服务返回的数据。

当我们希望调整后端服务地址时,只需要把 ROUTE_FILTER_ENTITY 表中的这条配置数据中的 url 字段改成其它的任何服务地址即可,大大增加了程序的灵活度。

以上就是“SpringCloud Gateway动态转发后端服务如何实现”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网精选频道。

--结束END--

本文标题: SpringCloud Gateway动态转发后端服务如何实现

本文链接: https://lsjlt.com/news/353794.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • SpringCloud Gateway动态转发后端服务如何实现
    今天小编给大家分享一下SpringCloud Gateway动态转发后端服务如何实现的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一...
    99+
    2023-07-05
  • Nacos+Spring Cloud Gateway动态路由如何配置实现
    小编给大家分享一下Nacos+Spring Cloud Gateway动态路由如何配置实现,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!前言  Nacos最近项目一直在使用,其简单灵活,支持更细粒度的命令空间,分组等为麻烦...
    99+
    2023-06-20
  • web开发移动端如何实现点击动态处理
    这篇文章主要介绍web开发移动端如何实现点击动态处理,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一、伪类:active :active伪类常用于设定点击状态下或其他被激活状态下一个...
    99+
    2024-04-02
  • SpringCloud如何使用Feign实现动态路由操作
    这篇文章主要介绍“SpringCloud如何使用Feign实现动态路由操作”,在日常操作中,相信很多人在SpringCloud如何使用Feign实现动态路由操作问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”S...
    99+
    2023-06-30
  • java后端如何实现页面跳转
    页面跳转分类有两种:重定向和转发,即redirect和forward。一:重定向redirect第一种方式:controller中返回值为String相关免费学习视频分享:java在线学习public String login(HttpSe...
    99+
    2019-10-12
    java教程 java 后端 实现 页面跳转
  • SpringCloud Alibaba微服务实战之如何禁止直接访问后端服务
    这篇文章主要讲解了“SpringCloud Alibaba微服务实战之如何禁止直接访问后端服务”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“SpringCl...
    99+
    2024-04-02
  • 教你如何实现SpringCloud URL的重定向及转发
    这篇文章主要介绍了SpringCloud URL重定向及转发代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下Web UI项目中, 很多 Spring controller 视图函数直...
    99+
    2023-06-02
  • 如何使用Golang实现简单的端口转发服务
    Golang(又称为Go)是由Google开发的一种开源编程语言。Golang具有高效、简洁、类C语言等特点,因此被广泛应用于网络编程。在网络编程中,端口转发是一个重要的技术。端口转发可以使一个计算机上的应用程序(例如Web服务器)能够访问...
    99+
    2023-05-14
  • SSH隧道动态转发端口实现SOCKS代理 + HTTP代理(Privoxy)
    一、文章概要 实现效果:ssh连接远程服务器进行网络转发,本地服务连接网络代理环境:windows11/10需要工具:MobaXterm(ssh隧道端口转发),Privoxy(socks转http代理),一个云服务器  二、步骤 1. 用S...
    99+
    2023-09-20
    ssh 服务器 运维
  • ios开发中如何实现模态跳转的动画设置
    这篇文章主要介绍ios开发中如何实现模态跳转的动画设置,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!模态跳转的动画设置设置模态跳转的动画,系统提供了四种可供选择DetailViewC...
    99+
    2024-04-02
  • SQL 如何实现动态的行列转置
    Oracle 和新版 Mysql 里有 pivot 实现行列转置,但实际处理数据时,会碰到一些更复杂的转置情况,pivot 也搞不定,比如: 想转置成: 这个难点在于事先不知道有多少种收入来源,而且每个人的收入来源种类各不相同。...
    99+
    2015-04-20
    SQL 如何实现动态的行列转置
  • nginx如何实现数据库端口转发
    这篇文章主要讲解了“nginx如何实现数据库端口转发”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“nginx如何实现数据库端口转发”吧!出于数据安全性考虑,正常情况下,网站或者项目的数据库一...
    99+
    2023-07-05
  • Golang如何用RPC实现转发服务
    今天小编给大家分享一下Golang如何用RPC实现转发服务的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。首先,我们需要了解一...
    99+
    2023-07-06
  • css如何实现移动端点击态处理
    小编给大家分享一下css如何实现移动端点击态处理,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、伪类:active ...
    99+
    2024-04-02
  • jquery中DataTable如何实现前后台动态分页
    小编给大家分享一下jquery中DataTable如何实现前后台动态分页,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!html代码:<!DOCTYPE html> &...
    99+
    2024-04-02
  • BootStrap中如何实现selectpicker后台动态绑定数据
    这篇文章主要介绍BootStrap中如何实现selectpicker后台动态绑定数据,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!html部分代码<select cl...
    99+
    2024-04-02
  • 如何实现data:image data url文件转为Blob上传后端
    这篇文章主要介绍如何实现data:image data url文件转为Blob上传后端,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一些场景,比如canvas获取的图片,或者微信开发...
    99+
    2024-04-02
  • springcloud中如何实现服务网关过滤器
    这篇文章将为大家详细讲解有关springcloud中如何实现服务网关过滤器,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。过滤器作用我们的微服务应用提供的接口就可以通过统一的API网关入口被客户端访问到了。...
    99+
    2023-06-05
  • SpringBoot动态定时任务如何实现
    这篇文章主要介绍了SpringBoot动态定时任务如何实现的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇SpringBoot动态定时任务如何实现文章都会有所收获,下面我们一起来看看吧。 执行定时任务的...
    99+
    2023-07-05
  • web开发如何实现移动端下拉加载动画
    这篇文章给大家分享的是有关web开发如何实现移动端下拉加载动画的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。  <!DOCTYPE html> &...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作