如果您(或正在考虑)使用微服务,那么您应该熟悉,或者至少要碰到API gateway pattern
。Chris Richardson在microservices.io上详细描述了这种模式。API网关充当系统的单一入口点,允许集中许多交叉问题,例如:路由机制,缓存管理,安全性,监控/指标和弹性。
在本文中,我们将探索Spring云套件中的一个新项目:Spring Cloud Gateway项目,构建于Spring 5,Spring Boot 2和Project Reactor之上。
Spring Cloud网关
当谈到选择为您的微服务的API网关,也有多种选择:Zuul来自Netflix,香港,Nginx的,HAProxy的,Traefik,云供应商的解决方案,如亚马逊的API网关或谷歌云端点和(新的)春云来自Pivotal的门户。
Spring Cloud Gateway旨在提供一种简单而有效的路由到API的方法。当它收到请求时,Spring Cloud Gateway会将其转发到网关处理程序映射,该映射确定应该对匹配特定路由的请求执行的操作。
我宁愿建立一个基于微服务的小型项目,而不是采用传统方法并列出所有功能,而是展示和描述它的用法
入门
在[github]上公开提供的极简主义项目(https://github.com/aboullaite/spring-cloud-gateway)由2个服务(BookStore和MovieStore),一个网关(显然基于Spring云网关)组成,服务发现(Eureka服务器)和Hystrix仪表板。该项目还需要运行和监听redis实例,以利用Spring Cloud Gateway的request.rate限制功能,
路由
Spring Cloud Gateway支持两种形式的创建路由:纯java(使用RouteLocator
)或配置文件。我们的项目使用第二种方法!
让我们来看看从一个片段application.yml
从gateway
模块:
spring: cloud: gateway: routes: - id: movie-store uri: lb://movie-store predicates: - Path=/api/movies/** filters: - name: RequestRateLimiter args: key-resolver: '#{@userKeyResolver}' redis-rate-limiter.replenishRate: 2 redis-rate-limiter.burstCapacity: 2 - RewritePath=/api/(?<movies>.*), /$\{movies} - AddResponseHeader=X-Some-Header, aboullaite.me
此配置告诉Spring Cloud Gateway将对网关发出的所有请求路由/api/movies/
到movie-store
服务。请注意谓词和过滤器的使用,因此我们可以根据特定条件路由句柄,并根据需要更改请求/响应。
值得一提的是,Spring Cloud Gateway有3个主要构建块:
- 路由:网关的主要API。它由ID,目标URI,谓词集合和过滤器集合定义。如果聚合谓词为真,则匹配路由。
- 谓词:Java 8函数谓词。它可以匹配HTTP请求中的任何内容,例如标头或参数。
- 过滤器:标准Spring框架
WebFilter
,可在发送下游请求之前或之后修改请求和响应。
您可能已经注意到,在上面的代码片段中我们使用了3 filters
:
AddResponseHeader
过滤以添加X-Some-Header
包含aboullaite.me
响应中的值的标头。RewritePath
过滤重写从请求路径/api/movies/**
到/movies/**
RequestRateLimiter
实施请求率限制器。
要阅读有关路由过滤器的更多信息,请参阅此链接。
限速
速率限制主要用于控制网络上发送或接收的流量速率。它有助于防止服务质量下降甚至由于高流量导致的中断,并提高API的可靠性。存在不同类型的速率限制,每种速率限制用于针对特定需求。
与zuul
没有集成开箱即用的速率限制解决方案不同,Spring Cloud Gateway附带了一个RequestRateLimiter
过滤器,用于确定是否允许当前请求继续进行。目前唯一支持的实现是redis
,需要使用spring-boot-starter-data-redis-reactive
Spring Boot启动器。
该RequestRateLimiter
有一个可选的keyResolver
参数和参数具体到速率限制器。请注意,key-resolver
引用带有名称的bean的SpEL表达式userKeyResolver
。此bean实现了KeyResolver
有助于派生限制请求的密钥的接口:
@Bean KeyResolver userKeyResolver() { return exchange -> Mono.just("fero"); }
我们还宣布了另外两个参数:
replenishRate
:表示允许用户每秒执行的请求数。burstCapacity
:定义用户在一秒钟内允许执行的最大请求数。
此外,此过滤器还添加了额外的标头,指示客户端的速率限制以及使用速度有多快:
X-RateLimit-Replenish-Rate
表示该replenishRate
值。X-RateLimit-Burst-Capacity
表示该burstCapacity
值。X-RateLimit-Remaining
表示您剩余的通话次数。
当请求提交超过补充率和突发限制时,网关会超出超出限制的请求并向429 Too Many Requests
客户端返回错误响应。
使用Hystrix
断路器是一种有趣的模式,可以提高您的API可靠性并防止网络或服务故障级联到其他服务和客户端。Spring Cloud Gateway附带Hystrix支持,这是一个实现断路器模式的Netflix库。
hystrix.command.fallbackcmd.execution.isolation.thread.timeoutInMilliseconds: 2000 spring: cloud: gateway: routes: - id: book-store uri: lb://book-store predicates: - Path=/api/books/** filters: - name: RequestRateLimiter args: key-resolver: '#{@userKeyResolver}' redis-rate-limiter.replenishRate: 2 redis-rate-limiter.burstCapacity: 2 - RewritePath=/api/(?<books>.*), /$\{books} - name: Hystrix args: name: booksFallbackCommand fallbackUri: forward:/fallback/books
该/books/danger
IN端点books-store
模块模拟性能差,需要一个很长的时间来发送它的响应的端点。我们还包裹,使用在该API的路线HystrixCommand
:booksFallbackCommand
。现在当Hystrix包裹的路由超时(即花费超过2秒)时,它将/fallback/books
在Gateway应用程序中调用端点,该应用程序只返回一个空列表:
@RestController @RequestMapping("/fallback") public class FallbackController { @GetMapping("/books") public ResponseEntity<List> booksFallback(){ return ResponseEntity.ok(Arrays.asList()); } }
请注意,此示例还通过lb
目标URI 上的前缀演示了Spring Cloud Netflix功能区负载平衡。
就是这篇文章!我们探讨了Spring Cloud Gateway中的一些功能和组件,主要是速率限制和断路器功能!我用过的项目可以在github上找到。