如何使用 Spring Cloud 实现网关

简介: 如何使用 Spring Cloud 实现网关

服务系统可能具有大量具有复杂交互的组件。降低这种复杂性非常重要,至少从客户端与系统交互的角度来看是这样。网关将微服务与外部世界隐藏起来。它代表了一个独特的入口,并实现了常见的交叉要求。在本文中,您将学习如何使用 Spring Cloud Gateway 包为 Spring Boot 应用程序配置网关组件。

Spring Cloud 网关

       Spring Cloud 通过 Spring Cloud Gateway 项目提供了一个网关实现。它基于 Spring Boot、Spring WebFlux 和 Reactor。由于它基于 Spring WebFlux,因此它必须在 Netty 环境中运行,而不是通常的 servlet 容器。

       网关的主要功能是将来自外部客户端的请求路由到微服务。其主要组成部分是:

路由:这是基本实体。它配置了 ID、目标 URI、一个或多个谓词和过滤器。

谓词:这基于 Java 函数谓词。它表示必须在 head 或 request 参数上匹配的条件。

过滤器:它允许您更改请求或响应。

我们可以识别以下事件序列:

客户端通过网关进行呼叫。

网关决定请求是否与配置的路由匹配。

如果存在匹配项,则将请求发送到网关 Web 处理程序。

Web 处理程序将请求发送到一系列过滤器,这些过滤器可以执行与请求或响应相关的逻辑,并对它们操作更改。

执行目标服务。

Spring Cloud 网关依赖项

       要将我们的 Spring Boot 应用程序实现为网关,我们必须首先在定义发布序列后提供依赖项,如下面的配置片段所示:spring-cloud-starter-gateway

XML格式

<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>2023.0.0</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

XML格式

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

Spring Cloud 网关配置

       我们可以使用 application.yaml 文件来配置我们的网关组件。我们可以指定完全扩展的参数或快捷方式来定义谓词和过滤器。在第一种情况下,我们定义了 a 和 an 字段。该字段可以包含一个或多个键值对:nameargsargs

YAML的

spring:
  cloud:
    gateway:
      routes:
      - id: route-example
        uri: https://example.com
        predicates:
        - name: PredicateExample
          args:
            name: predicateName
            regexp: predicateRegexpValue

在上面的示例中,我们定义了一个 ID 值为 “”的路由、一个目标 URI “,”和一个包含两个 “” 和 “” 的谓词。route-examplehttps://example.comargsnameregexp

使用快捷方式模式,我们编写谓词名称,后跟“”字符,然后用逗号分隔名称和值列表。我们可以通过以下内容重写上一个示例:=

YAML的

spring:
  cloud:
    gateway:
      routes:
      - id: route-example
        uri: https://example.com

        predicates:
        - Cookie=predicateName,predicateRegexpValue

特定的工厂类实现每个谓词和筛选器类型。有几个内置的谓词和过滤器工厂可用。上面显示的谓词就是一个示例。我们将在以下小节中列出其中的一些。Cookie

谓词内置工厂

在特定时间之后发生的匹配请求。After Predicate Factory

After=2007-12-03T10:15:30+01:00 Europe/Paris

在特定时间之前发生的匹配请求。Before Predicate Factory

Before=2007-12-03T10:15:30+01:00 Europe/Paris

指定要匹配的 HTTP 方法类型。Method Route Predicate Factory

Method=GET,POST

过滤器内置工厂

允许按其名称和值将 HTTP 标头添加到请求中。AddRequestHeader GatewayFilter Factory

AddRequestHeader=X-Request-Foo,条形图

允许按其名称和值向请求添加参数。AddRequestParameter GatewayFilter Factory

AddRequestParameter=foo,柱线

允许按其名称和值将 HTTP 标头添加到请求中。AddResponseHeader GatewayFilter Factory

AddResponseHeader=X-Response-Foo,条形图

       要实现自定义谓词或滤波器工厂,我们必须提供特定工厂接口的实现。以下各节演示如何操作。

自定义谓词工厂

       要创建自定义谓词工厂,我们可以扩展接口的抽象实现。在下面的示例中,我们定义了一个内部静态类,以将其属性传递给 apply 方法并将它们与请求进行比较。AbstractRoutePredicateFactoryRoutePredicateFactoryConfiguration

爪哇岛

@Component
public class CustomPredicateFactory extends AbstractRoutePredicateFactory<CustomPredicateFactory.Configuration> {

    public CustomPredicateFactory() {
        super(Configuration.class);
    }

    @Override
    public Predicate<ServerWebExchange> apply(Configurationconfig) {
        return exchange -> {
            ServerHttpRequest request = exchange.getRequest();
            //compare request with config properties
            return matches(config, request);
        };
    }

    private boolean matches(Configuration config, ServerHttpRequest request) {
        //implement matching logic
        return false;
    }

    public static class Configuration{
        //implement custom configuration properties
    }
}

定制过滤器工厂

       为了创建一个自定义的过滤器工厂,我们可以扩展接口的抽象实现。在下面的示例中,您可以看到一个过滤器工厂,该工厂使用对象传递的属性修改请求,另一个过滤器工厂使用对象传递的属性更改响应。AbstractGatewayFilterFactoryGatewayFilterFactoryConfiguration

爪哇岛

@Component
public class PreCustomFilterFactory extends AbstractGatewayFilterFactory<PreCustomFilterFactory.Configuration> {

    public PreCustomFilterFactory() {
        super(Configuration.class);
    }

    @Override
    public GatewayFilter apply(Configuration config) {
        return (exchange, chain) -> {
            ServerHttpRequest.Builder builder = exchange.getRequest().mutate();
            //use builder to modify the request
            return chain.filter(exchange.mutate().request(builder.build()).build());
        };
    }

    public static class Configuration {
        //implement the configuration properties
    }

}

@Component
public class PostCustomFilterFactory extends AbstractGatewayFilterFactory<PostCustomFilterFactory.Configuration> {

    public PostCustomFilterFactory() {
        super(Configuration.class);
    }

    @Override
    public GatewayFilter apply(Configuration config) {
        return (exchange, chain) -> {
            return chain.filter(exchange).then(Mono.fromRunnable(() -> {
                ServerHttpResponse response = exchange.getResponse();
                    //Change the response
            }));
        };
    }

    public static class Configuration {
        //implement the configuration properties
    }

}

Spring Cloud 网关示例

       我们将展示一个实用而简单的示例,以了解网关在真实场景中是如何工作的。您将在文章末尾找到源代码的链接。该示例基于以下堆栈:

Spring Boot:3.2.1

Spring Cloud:2023.0.0  

爪哇 17

       我们考虑一个最小的微服务系统,它实现了一个只有两个服务的库:一个服务和一个服务。该服务通过传递参数来调用服务以检索作者的信息。这两个应用程序的实现基于嵌入式内存 H2 数据库,并使用 JPA ORM 来映射和查询 and 表。从本演示的角度来看,最重要的部分是服务类公开的 REST 端点:bookauthorbookauthorauthorNameBookAuthor/getAuthorBookControllerBook

爪哇岛

@RestController
@RequestMapping("/library")
public class BookController {

    Logger logger = LoggerFactory.getLogger(BookService.class);

    @Autowired
    private BookService bookService;

    @GetMapping(value = "/getAuthor", params = { "authorName" })
    public Optional<Author> getAuthor(@RequestParam("authorName") String authorName) {
        return bookService.getAuthor(authorName);
    }
}

这两个应用程序在 Eureka 发现服务器中注册自己,并配置为发现客户端。最后一个组件是网关。网关不应将自身注册到服务发现服务器。这是因为它仅由外部客户端调用,而不是由内部微服务调用。另一方面,它可以配置为发现客户端,以自动获取其他服务并实现更动态的路由。不过,我们在这里这样做不是为了让事情变得简单。

在此示例中,我们想要展示两件事:

了解谓词值的路由机制的工作原理

演示如何通过过滤器修改请求,添加标题

网关的配置如下:

爪哇岛

spring:
   application:
      name: gateway-service
   cloud:
      gateway:
         routes:
            - id: add_request_header_route
              uri: http://localhost:8082
              predicates:
                 - Path=/library/**
              filters:
                 - AddRequestHeader=X-Request-red, red

我们定义了一个 id 为 “,” 的路由,URI 值为 “”,这是预订服务的基本 URI。然后,我们有一个值为 “” 的谓词。每个以 “” 开头的调用都将匹配并使用以 “” 开头的 URI 路由到书籍的服务。add_request_header_routehttp://localhost:8082Path/library/**http://localhost:8080/library/http://localhost:8082/library/

运行示例

       要运行该示例,您可以通过从组件的基目录中执行 “” 命令来启动每个组件。然后,您可以通过执行 “” URI 来测试它。结果将是一个 JSON 值,其中包含有关作者的信息。如果您查看浏览器开发人员工具,您还会发现已将值为“.”的标头添加到请求中。mvn spring-boot:runhttp://localhost:8080/library/getAuthor?authorName=GoetheX-Request-redred

       在Spring Boot框架中,使用Spring Cloud Gateway包实现网关是自然的选择。它通过在微服务环境前面放置单个立面组件来降低微服务环境的复杂性。它还为实现跨领域关注点(如身份验证、授权、聚合日志记录、跟踪和监视)提供了极大的灵活性。


目录
相关文章
|
26天前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
2天前
|
人工智能 Rust Java
10月更文挑战赛火热启动,坚持热爱坚持创作!
开发者社区10月更文挑战,寻找热爱技术内容创作的你,欢迎来创作!
308 14
|
18天前
|
存储 关系型数据库 分布式数据库
GraphRAG:基于PolarDB+通义千问+LangChain的知识图谱+大模型最佳实践
本文介绍了如何使用PolarDB、通义千问和LangChain搭建GraphRAG系统,结合知识图谱和向量检索提升问答质量。通过实例展示了单独使用向量检索和图检索的局限性,并通过图+向量联合搜索增强了问答准确性。PolarDB支持AGE图引擎和pgvector插件,实现图数据和向量数据的统一存储与检索,提升了RAG系统的性能和效果。
|
5天前
|
JSON 自然语言处理 数据管理
阿里云百炼产品月刊【2024年9月】
阿里云百炼产品月刊【2024年9月】,涵盖本月产品和功能发布、活动,应用实践等内容,帮助您快速了解阿里云百炼产品的最新动态。
阿里云百炼产品月刊【2024年9月】
|
20天前
|
人工智能 IDE 程序员
期盼已久!通义灵码 AI 程序员开启邀测,全流程开发仅用几分钟
在云栖大会上,阿里云云原生应用平台负责人丁宇宣布,「通义灵码」完成全面升级,并正式发布 AI 程序员。
|
22天前
|
机器学习/深度学习 算法 大数据
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
2024“华为杯”数学建模竞赛,对ABCDEF每个题进行详细的分析,涵盖风电场功率优化、WLAN网络吞吐量、磁性元件损耗建模、地理环境问题、高速公路应急车道启用和X射线脉冲星建模等多领域问题,解析了问题类型、专业和技能的需要。
2584 22
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
|
4天前
|
存储 人工智能 搜索推荐
数据治理,是时候打破刻板印象了
瓴羊智能数据建设与治理产品Datapin全面升级,可演进扩展的数据架构体系为企业数据治理预留发展空间,推出敏捷版用以解决企业数据量不大但需构建数据的场景问题,基于大模型打造的DataAgent更是为企业用好数据资产提供了便利。
177 2
|
2天前
|
编译器 C#
C#多态概述:通过继承实现的不同对象调用相同的方法,表现出不同的行为
C#多态概述:通过继承实现的不同对象调用相同的方法,表现出不同的行为
102 65
|
6天前
|
Linux 虚拟化 开发者
一键将CentOs的yum源更换为国内阿里yum源
一键将CentOs的yum源更换为国内阿里yum源
283 2
|
22天前
|
机器学习/深度学习 算法 数据可视化
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
2024年中国研究生数学建模竞赛C题聚焦磁性元件磁芯损耗建模。题目背景介绍了电能变换技术的发展与应用,强调磁性元件在功率变换器中的重要性。磁芯损耗受多种因素影响,现有模型难以精确预测。题目要求通过数据分析建立高精度磁芯损耗模型。具体任务包括励磁波形分类、修正斯坦麦茨方程、分析影响因素、构建预测模型及优化设计条件。涉及数据预处理、特征提取、机器学习及优化算法等技术。适合电气、材料、计算机等多个专业学生参与。
1580 16
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码