β

Spring Cloud Gateway中的过滤器工厂:重试过滤器

Harries Blog™ 807 阅读

Spring Cloud Gateway基于 Spring Boot 2,是Spring Cloud的全新项目,该项目提供了一个构建在Spring 生态之上的 API 网关。本文基于的Spring Cloud版本为 Finchley M9 ,Spring Cloud Gateway对应的版本为 2.0.0.RC1

Spring Cloud Gateway入门 一文介绍了全新的Spring Cloud Gateway的一些基础应用。本文将会介绍Spring Cloud Gateway重试过滤器。

过滤器

GatewayFilter 网关过滤器用于拦截和链式处理 web 请求,可以实现横切的、与应用无关的 需求 ,比如 安全 、访问超时的设定等等。

public interface GatewayFilter{
	Mono<Void>filter(ServerWebExchange exchange, GatewayFilterChain chain);
}

接口中定义了唯一的方法 #filter ,处理web请求,并且可以通过给定的过滤器链传递到下一个过滤器。该接口有多个实现类,下面看一下该接口的类图。

Spring Cloud Gateway中的过滤器工厂:重试过滤器 从类图可以看到, GatewayFilter 有两个实现类,但是在 源码 中寻找该接口的用法会发现,在 GatewayFilterFactory 实现类中有内部匿名类,实际是返回了一个 GatewayFilter 内部实现类。

Spring Cloud Gateway提供了很多种类的过滤器工厂,网关过滤器有近二十个实现类,总得说来可以分为七类:Header、Parameter、Path、Status、Redirect跳转、 Hystrix 熔断和RateLimiter限流等。

重试过滤器

请求的重试

当转发到代理服务时,遇到指定的 服务端 Error,如 http Status为500时,我们可以设定重试几次。除了对指定的异常重试之外,还可以指定请求的方法,GET或POST。

实验场景涉及到:网关服务和用户服务。客户端请求经过网关,请求用户服务的API接口,遇到指定的异常时,进行重试。

项目准备

示例启动两个服务:Gateway-Server和user-Server。模拟的场景是,客户端请求后端服务,网关提供后端服务的统一入口。后端的服务都注册到服务发现Consul(搭建zk, Eureka 都可以,笔者比较习惯使用 consul )。网关通过 负载均衡 转发到具体的后端服务。

用户服务

用户 服务注册 到Consul上,并提供一个接口/test。

网关服务

引入网关的依赖,并进行相应 配置 。上一章已经讲过,这里不重复列出 代码 ,具体见源码。

服务改造

网关服务

网关服务中,新增一个路由的定义 retry_ java ,请求的判定是路径以 /test 为前缀的请求,并将请求转发到user服务。当遇到内部服务错误(状态码为500)时,设定重试的次数为2。当然该路由也可以通过网关服务的配置文件,效果是一样的。

  @Bean
  public RouteLocator retryRouteLocator(RouteLocatorBuilder builder){
      return builder.routes()
              .route("retry_java", r -> r.path("/test/**")
                      .filters(f -> f.stripPrefix(1)
                              .retry(config -> config.setRetries(2).setStatuses(HttpStatus.INTERNAL_SERVER_ERROR)))
	.uri("lb://user"))
.build();
  }

用户服务

用户服务增加一个API接口,请求中传入 参数 key 和count。

ConcurrentHashMap<String, AtomicInteger> map = new ConcurrentHashMap<>();

@GetMapping("/exception")
public String testException(@RequestParam("key")String key, @RequestParam(name ="count", defaultValue ="3")int count) {
    AtomicInteger num = map.computeIfAbsent(key, s -> new AtomicInteger());
    int i = num.incrementAndGet();
    log.warn("Retry count: "+i);
    if (i < count) {
        throw new RuntimeException("temporarily broken");
    }
    return String.valueOf(i);
}

这里主要是为了能配置网关请求次数的演示,count是指定的重试次数,默认为3,第一次和第二次都会抛出运行时异常(状态码为500),变量 i 是key对应的值,初始为0,每重试一次,i 会递增,直到 i 大于等于count的值。

测试 结果

根据上面的实现,我们访问的地址为 http://localhost:9090/test/exception?key=abc&count=2

按照用户服务实现的逻辑,用户服务将会重试一次即可成功。用户服务的控制台日志信息如下:

Retry count: 1

java.lang.IllegalArgumentException: temporarily broken] with root cause
...
Retry count: 2

Spring Cloud Gateway中的过滤器工厂:重试过滤器

控制台的信息和最后的响应结果可以看出,请求的重试执行成功。

小结

本文在 Spring Cloud Gateway入门 的基础上,介绍了Spring Cloud Gateway的过滤器相关概念,并具体介绍了其中的一个过滤器工厂: RetryGatewayFilterFactory 。当转发到代理服务时,遇到指定的服务端Error,如httpStatus为500时,我们可以设定重试几次,应用重试过滤器。Spring Cloud Gateway提供了很多过滤器工厂的实现,后面 文章 将会介绍其中比较重要的过滤器,敬请关注。

原文

http://blueskykong.com/2018/04/25/cloud-Gateway-filter-1/

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。 PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处: Harries Blog™ » Spring Cloud Gateway中的过滤器工厂:重试过滤器

作者:Harries Blog™
追心中的海,逐世界的梦
原文地址:Spring Cloud Gateway中的过滤器工厂:重试过滤器, 感谢原作者分享。

发表评论