spring-cloud-gateway

Spring Cloud Gateway 全局异常处理

1、概览 本文将带你了解如何在 Spring Cloud Gateway 中实现全局异常处理。 在现代软件开发中,尤其是在微服务中,API 的高效管理至关重要。这正是 Spring Cloud Gateway 作为 Spring 生态系统的关键组件发挥重要作用的地方。它就像一个门卫,将流量和请求引导到适当的微服务,并提供跨切面的关注点,如安全性、监控/指标和弹性。 然而,在如此复杂的环境中,由于网络故障、服务宕机或应用错误而产生的异常是必然的,这就需要一个强大的异常处理机制。Spring Cloud Gateway 的全局异常处理可确保在所有服务中采用一致的错误处理方法,并增强整个系统的弹性和可靠性。 2、全局异常处理的必要性 Spring Cloud Gateway 是 Spring 生态系统中的一个项目,旨在作为微服务架构中的 API 网关,其主要作用是根据预先制定的规则将请求路由到相应的微服务。网关提供安全(认证和授权)、监控和熔断(Circuit Breakers)等功能。通过处理请求并将其导向适当的后端服务,它有效地管理了诸如安全性和流量管理等横切关注点。 在微服务等分布式系统中,异常可能来自多个方面,如网络问题、服务不可用、下游服务错误和应用级错误,这些都是常见的罪魁祸首。在这种环境下,以本地化方式(即在每个服务内)处理异常可能会导致零散和不一致的错误处理。这种不一致性会使调试工作变得繁琐,并降低用户体验: 全局异常处理通过提供集中的异常管理机制,确保所有异常(无论其来源如何)都能得到一致的处理,并提供标准化的错误响应,从而应对这一挑战。 这种一致性对于系统恢复能力、简化错误跟踪和分析至关重要。它还能提供精确一致的错误格式,帮助用户了解出错的原因,从而提升用户体验。 3、在 Spring Cloud Gateway 中实现全局异常处理 在 Spring Cloud Gateway 中实现全局异常处理涉及几个关键步骤,每个步骤都能确保建立一个强大而高效的异常管理系统。 3.1、创建自定义全局异常处理器 全局异常处理器对于捕获和处理网关中发生的异常至关重要。为此,需要继承 AbstractErrorWebExceptionHandler 并将其添加到 Spring Context 中。这样,就创建了一个能拦截所有异常的集中式处理器。 @Component public class CustomGlobalExceptionHandler extends AbstractErrorWebExceptionHandler { // 构造函数和其他方法 } 该类应能处理各种类型的异常,从 NullPointerException 等一般异常到 HttpClientErrorException 等更具体的异常。目标是涵盖各种可能的错误。该类的核心方法如下所示。 @Override protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) { return RouterFunctions.

自定义 Spring Cloud Gateway 过滤器(Filter)

1、概览 上一篇文章《Spring Cloud Gateway 教程》中介绍了 Spring Cloud Gateway 网关框架。本文将带你了解如何在 Spring Cloud Gateway 中自定义 Filter。以及如何在 Filter 中修改请求和响应数据。 2、项目设置 创建一个基本应用,并将其用作 API 网关。 2.1、Maven 配置 在使用 Spring Cloud 时,往往通过 <dependencyManagement> 来管理组件的版本: <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR4</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> 添加 Spring Cloud Gateway,无需指定使用的实际版本: <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> 最新的 Spring Cloud 版本可通过 Maven Central 中找到。当然,需要注意使用的 Spring Cloud 版本需要与 Spring Boot 版本兼容。 2.2、API 网关配置 假设 API 服务在本地 8081 端口运行,在 /resource 端点暴露了一个简单的字符串资源。 接下来,配置网关,把请求代理到该服务。简而言之,当请求网关的 URI 路径中带有 /service 前缀的请求时,网关将把请求转发给该服务。

Spring Cloud Gateway 教程

1、概览 本文将带你了解 Spring Cloud Gateway 的主要功能,它是一个基于 Spring Boot 和 Project Reactor 的网关。 Spring Cloud Gateway 提供开箱即用的路由机制,通常用于微服务应用中,把多个服务隐藏在 “Facade”(门面设计模式)后面。 2、路由处理器 Spring Cloud Gateway 专注于路由请求,它将请求转发给网关 Handler Mapping,由其决定如何处理与特定路由相匹配的请求。 从一个快速示例开始,看看 Gateway Handler 如何使用 RouteLocator 解析路由配置: @Bean public RouteLocator customRouteLocator(RouteLocatorBuilder builder) { return builder.routes() .route("r1", r -> r.host("**.baeldung.com") .and() .path("/baeldung") .uri("http://baeldung.com")) .route(r -> r.host("**.baeldung.com") .and() .path("/myOtherRouting") .filters(f -> f.prefixPath("/myPrefix")) .uri("http://othersite.com") .id("myOtherID")) .build(); } 注意,有几个核心的 API: Route - 网关的主要 API。它由给定的标识(ID)、目的地(URI)和一组 Predicate 和 Filter 定义 Predicate - Java 8 Predicate ,用于使用 Header、方法或参数匹配 HTTP 请求 Filter - 标准的 Spring WebFilter 3、动态路由 与 Zuul 一样,Spring Cloud Gateway 也提供了将请求路由到不同服务的方法。

Spring Cloud Gateway 和 Oauth2

1、概览 Spring Cloud Gateway 是一个响应式的轻量级网关,是 Spring Cloud 体系中一个比较重要的组件。本文将带你了解如何在其基础上快速实现 OAuth 2.0 认证、授权。 2、OAuth 2.0 快速回顾 OAuth 2.0 标准是一个成熟的标准,在互联网上广泛使用,是用户和应用安全访问资源的一种安全机制。 其中涉及的关键术语如下: Resource(资源):只有经过授权的客户端才能检索的任何类型的信息。 Client(客户端):消费资源的应用,通常通过 REST API 消费资源。 Resource Server(资源服务器):负责向授权客户端提供资源的服务。 Resource Owner(资源所有者):实体(人或应用),拥有资源,并最终负责向客户端授予对该资源的访问权限。 Token(令牌):客户端获取的一段信息,并作为请求的一部分发送给资源服务器以进行身份验证。 Identity Provider(身份提供商,即 IDP):验证用户凭证并向客户端发放 Access Token。 Authentication Flow(认证模式/流程):客户端获得有效 Token 必须经过的一系列步骤。 你可以通过 Auth0 的相关文档了解更多详细内容。 3、OAuth 2.0 模式 Spring Cloud Gateway 主要用于以下用途之一: OAuth Client(客户端) OAuth Resource Server(资源服务器) 我们来逐个了解。 3.1、Spring Cloud Gateway 作为 OAuth 2.0 客户端 在这种情况下,任何未经身份认证的传入请求都将触发授权码流程。一旦网关获取到 Token,它将在向后端服务发起请求时使用该 Token。 在实际应用中,一个很好的例子是聚合了 “社交应用” 的应用:对于每个支持的社交应用,网关将充当 OAuth 2.0 客户端。 因此,前端(通常是使用 Angular、React 或类似 UI 框架构建的 SPA 应用)可以代表终端户无缝访问这些应用上的数据。更重要的是:用户无需暴露自己的凭证。

Spring Cloud Gateway 重写 URL

1、简介 Spring Cloud Gateway 的常见用例是作为一个网关,代理一个或多个服务,从而为客户端提供更简单的消费方式。 本文将带你了解如何在将请求发送到后端之前,通过重写 URL 来自定义暴露的 API 的不同方式。 2、Spring Cloud Gateway 快速回顾 Spring Cloud Gateway 项目是在流行的 Spring Boot 2 和 Project Reactor 的基础上构建的,因此继承了其主要特性: 响应式,资源占用低 支持 Spring Cloud 生态系统的所有功能(服务发现、配置等) 使用标准 Spring 模式轻松扩展和/或定制 这里只列出它的主要概念,更多详细信息请参阅 中文文档: Route:路由,在网关中,匹配的传入请求会经历一系列的处理步骤。 Predicate:针对 ServerWebExchange 进行评估的 Java 8 Predicate。 Filters:可以检查、更改 ServerWebExchange 的 GatewayFilter 实例。网关支持全局 Filter 和按路由的 Filter。 简而言之,接收请求的处理顺序如下: 网关使用与每条路由相关的 Predicate 来查找哪条路由可以处理请求。 一旦找到路由,请求(ServerWebExchange 实例)就会通过每个配置的 Filter,直到最终发送到后端。 当后端发送回响应或出现错误(例如超时或连接重置)时,Filter 可以再次处理响应,然后再将其发送回客户端。 3、基于配置的 URL 重写 回到本文的主题,让我们看看如何定义一个路由,在将请求发送到后端之前重写传入的 URL。例如,假设输入的请求格式为 /api/v1/customer/*,后端 URL 应为 http://v1.customers/api/*。这里,使用 “*” 来表示 “在此之后的任何内容”。

在 Spring Cloud Gateway 中修改响应体

1、简介 本文将带你了解如何在 Spring Cloud Gateway 中读取、修改响应体,然后再响应给客户端。 2、Spring Cloud Gateway 快速回顾 Spring Cloud Gateway(简称 SCG)是 Spring Cloud 系列中的一个子项目,它提供了一个构建在响应式 Web 栈之上的 API 网关。关于它的更多详细信息和用法,你可以参考 官方文档。 设计 API Gateway 解决方案时经常出现的一种特殊使用场景:如何在将后端响应的 Body 发送回客户端之前对其进行处理? 下面列出了一些可能会用到这种功能的场景: 保持与现有客户端的兼容性,同时允许后台不断迭代 需要屏蔽响应中的某些敏感字段(脱敏) 实现这个需求,只需要实现一个 Filter 来处理后台响应即可。Filter 是 SCG 的核心概念。 Filter 组件创建后就可以将其应用于任何已声明的路由(Route)。 3、实现数据过滤 Filter 创建一个简单的 Filter 来屏蔽 JSON 响应中的某些值。 例如,给定的 JSON 有一个名为 “ssn” 的字段: { "name" : "John Doe", "ssn" : "123-45-9999", "account" : "9999888877770000" } 我们希望用一个固定的值进行替换,从而防止数据泄漏: { "name" : "John Doe", "ssn" : "****", "account" : "9999888877770000" } 3.

Spring Cloud 2023 新特性:支持同步网关

网关不支持传统 Servlet 容器 Spring Cloud Gateway 需要运行在提供的 Netty 运行时。它不能在传统的 Servlet 容器中工作,也不能在构建为 WAR 时工作。WebFlux 使用了异步非阻塞的编程模型,相较于传统的 MVC Servlet 需要理解和适应新的编程范式和响应式编程概念,因此学习曲线可能较陡峭。 如果在 spring-cloud-gateway 引入了 tomcat 等传统容器会抛出如下异常: 14 Caused by: org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat 15 at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:124) ~[spring-boot-2.1.6.RELEASE.jar:2.1.6.RELEASE] 16 at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.<init>(TomcatWebServer.java:86) ~[spring-boot-2.1.6.RELEASE.jar:2.1.6.RELEASE] 17 at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getTomcatWebServer(TomcatServletWebServerFactory.java:414) ~[spring-boot-2.1.6.RELEASE.jar:2.1.6.RELEASE] 18 at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:178) ~[spring-boot-2.1.6.RELEASE.jar:2.1.6.RELEASE] 19 at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:179) ~[spring-boot-2.1.6.RELEASE.jar:2.1.6.RELEASE] 20 at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:152) ~[spring-boot-2.1.6.RELEASE.jar:2.1.6.RELEASE] 21 ... 8 common frames omitted MVC Servlet 支持 在 SpringCloud 2023 版本(Spring Cloud Gateway 4.

Spring Cloud Gateway 根据客户端 IP 限制请求速率

1、简介 在本教程中,我们将学习如何在 Spring Cloud Gateway 中根据客户端的实际 IP 地址来限制请求速率。 简而言之,我们将在路由上设置 RequestRateLimiter Filter,然后配置网关根据 IP 地址来限制客户端的请求。 2、路由配置 首先,我们需要配置 Spring Cloud Gateway 以对特定路由进行速率限制。为此,我们将使用由 spring-boot-starter-data-redis-reactive 实现的经典 令牌桶(Token Bucket) Rate Limiter。简而言之, Rate Limiter 创建一个带有唯一 Key 的 Bucket,该 Key 用于标识 Bucket 自身,并具有固定的初始 Token 容量,随时间自动生成 Token。然后,对于每个请求,Rate Limiter 会获取其关联的 Bucket,并试图减少其 Bucket 中的一个 Token。如果 Bucket 中的 Token 数量不足,将拒绝传入的请求。 在分布式系统中,我们希望所有系统对同一客户端的请求都采用相同的限速策略。所以,我们使用分布式缓存 Redis 来存储 Bucket。在本例中,我们预先配置了一个 Redis 实例。 接下来,配置一个带有 Rate Limiter 的路由。监听 /example 端点,并将请求转发至 http://example.org: @Bean public RouteLocator myRoutes(RouteLocatorBuilder builder) { return builder.routes() .route("requestratelimiter_route", p -> p .

Spring Cloud Gateway 的主动健康检查策略

如今,应用程序被构建为小型独立上游服务的集合。这加快了开发速度,并使模块专注于特定职责,提高了质量。这是使用微服务方法的主要优势之一。然而,从一个服务跳转到另一个服务会增加额外的延迟,当服务没有响应时,这种延迟会显著增加。 如果你运行的是微服务,你需要防止上游服务在工作不正常时被调用。即使使用断路器(circuit breaker)模式,也会对响应时间造成影响。因此,有时最好主动检查上游服务,以验证它们是否在需要之前就已准备就绪。 健康检查是确定服务是否能够根据其状态作出正确响应、防止超时和错误的一种方法。 被动健康检查 在请求处理过程中进行。如果服务最终处于不健康状态,应用程序将返回失败,并标记端点不健康。这会增加额外的延迟。 主动健康检查 将在接收请求之前在后台检查并放弃不健康的服务。它不会增加额外的延迟。 最后但并非最不重要的一点是,这些功能可与断路器库结合使用,以便立即 fall back 到另一个 endpoint ,而不会受到首次失误的惩罚。 目标是通过使用负载均策略,将路由请求转发到健康的上游服务: 本文章分为两部分: “你需要的 Spring 功能” - 描述你需要哪些 Spring 功能来获得主动的健康检查。 “为你的服务注册端点”- 参考一些将一个或多个端点添加到路由中的方法。 1、你需要的 Spring 功能 Spring 的一些功能可以帮助你进行主动的健康检查: Spring Cloud Load Balancer(SLB)是客户端负载均衡器,可在不同上游服务端点之间均衡流量。它是 Spring Cloud 项目 的一部分,包含在 spring-cloud-commons 库中(参见 SLB文档)。 客户端服务发现功能可让客户端查找服务并与之通信,而无需硬编码主机名和端口。spring-cloud-commons 库中也包含该功能(参见 服务发现文档)。 Spring Cloud Gateway 为在 Spring 和 Java 之上构建API网关提供了一个库。它通过 LoadBalancerClientFilter / ReactiveLoadBalancerClientFilter 全局过滤器支持上述功能。在本文章中,你将看到使用这些全局过滤器的不同方法。 首先,让我们来了解其中的一些功能。 Spring Cloud Load Balancer filter Spring Cloud 中包含用于负载均衡的全局过滤器,可通过使用特殊的 URI 符号激活:lb://your-service-name。 spring: cloud: gateway: routes: - id: myRoute uri: lb://your-service-name predicates: - Path=/service/** 负载均衡器过滤器 ReactiveLoadBalancerClientFilter (用于响应式应用程序)将检测 URI 并将其替换为与 your-service-name 相关的可用端点。