如果您(或正在考虑)使用微服务,那么您应该熟悉,或者至少要碰到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-reactiveSpring 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/dangerIN端点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上找到。
