前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring Cloud Gateway中的过滤器工厂:重试过滤器

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

作者头像
aoho求索
发布2018-07-25 17:29:46
1.5K0
发布2018-07-25 17:29:46
举报
文章被收录于专栏:aoho求索aoho求索

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请求,可以实现横切的、与应用无关的需求,比如安全、访问超时的设定等等。

代码语言:javascript
复制
1public interface GatewayFilter {
2    Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
3}

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

GatewayFilter

从类图可以看到,GatewayFilter有两个实现类,但是在源码中寻找该接口的用法会发现,在GatewayFilterFactory实现类中有内部匿名类,实际是返回了一个 GatewayFilter 内部实现类。

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

重试过滤器

请求的重试

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

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

项目准备

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

用户服务

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

网关服务

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

服务改造

网关服务

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

代码语言:javascript
复制
1    @Bean
2    public RouteLocator retryRouteLocator(RouteLocatorBuilder builder) {
3        return builder.routes()
4                .route("retry_java", r -> r.path("/test/**")
5                        .filters(f -> f.stripPrefix(1)
6                                .retry(config -> config.setRetries(2).setStatuses(HttpStatus.INTERNAL_SERVER_ERROR)))
7            .uri("lb://user"))
8        .build();
9    }
用户服务

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

代码语言:javascript
复制
 1    ConcurrentHashMap<String, AtomicInteger> map = new ConcurrentHashMap<>();
 2
 3    @GetMapping("/exception")
 4    public String testException(@RequestParam("key") String key, @RequestParam(name = "count", defaultValue = "3") int count) {
 5        AtomicInteger num = map.computeIfAbsent(key, s -> new AtomicInteger());
 6        int i = num.incrementAndGet();
 7        log.warn("Retry count: "+i);
 8        if (i < count) {
 9            throw new RuntimeException("temporarily broken");
10        }
11        return String.valueOf(i);
12    }

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

测试结果

根据上面的实现,我们访问的地址为http://localhost:9090/test/exception?key=abc&count=2。 按照用户服务实现的逻辑,用户服务将会重试一次即可成功。用户服务的控制台日志信息如下:

代码语言:javascript
复制
1Retry count: 1
2java.lang.IllegalArgumentException: temporarily broken] with root cause
3...
4Retry count: 2

请求的响应结果

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

小结

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

源码地址

https://github.com/keets2012/Spring-Cloud_Samples

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-04-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 aoho求索 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 过滤器
  • 重试过滤器
    • 请求的重试
      • 项目准备
        • 用户服务
        • 网关服务
      • 服务改造
        • 网关服务
        • 用户服务
        • 测试结果
    • 小结
      • 源码地址
      相关产品与服务
      负载均衡
      负载均衡(Cloud Load Balancer,CLB)提供安全快捷的流量分发服务,访问流量经由 CLB 可以自动分配到云中的多台后端服务器上,扩展系统的服务能力并消除单点故障。负载均衡支持亿级连接和千万级并发,可轻松应对大流量访问,满足业务需求。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档