zoukankan      html  css  js  c++  java
  • spring cloud 2.x版本 Gateway熔断、限流教程

    前言

    本文采用Spring cloud本文为2.1.8RELEASE,version=Greenwich.SR3
    

    本文基于前两篇文章eureka-server、eureka-client、eureka-ribbon、eureka-feign和spring-gataway的实现。
    参考

    概术

    在高并发应用中,缓存、限流、降级,是我们保护系统应用的三大利器。在开发一些api接口的时候,通常也会在网关层做限流控制,一方面是为了防止大量的请求是服务器过载,导致服务器不可用,另一方面也是防止其他人的恶习网络攻击。

    常见的限流方式,如Hystrix的使用线程池隔离,超过线程池的负载走熔断的逻辑;也有通过滑动的时间窗口来控制流量。

    常用的限流算法有,计数器算法、漏桶算法、令牌桶算法,这里就不对相关算法进行描述。

    熔断

    Spring Cloud Gateway的熔断可以基于Hystrix实现。可以参考spring cloud 2.x版本 Hystrix Dashboard断路器教程

    1.1 增加pom相关依赖

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
    

    1.2 修改application.yml

    server:
      port: 8100
    spring:
      redis:
        host: localhost
        port: 6379
      application:
        name: spring-gateway
      cloud:
          gateway:
            discovery:
              locator:
                enabled: true # 开启通过服务中心的自动根据 serviceId 创建路由的功能
            default-filters:
              - My=true
            routes:
              - id: ribbon-route
                uri: lb://EUREKA-RIBBON
                order: 0
                predicates:
                  - Path=/ribbon/**
                filters:
                  - name: Hystrix
                    args:
                      name: fallback
                      fallbackUri: forward:/fallback
                  - StripPrefix=1 #去掉前缀,具体实现参考StripPrefixGatewayFilterFactory
                  - AddResponseHeader=X-Response-Default-Foo, Default-Bar
              - id: feign-route
                uri: lb://EUREKA-FEIGN
                order: 0
                predicates:
                  - Path=/feign/**
                filters:
                  - StripPrefix=1
                  - AddResponseHeader=X-Response-Default-Foo, Default-Bar
    
    eureka:
      instance:
        hostname: eureka1.server.com
        lease-renewal-interval-in-seconds: 5
        lease-expiration-duration-in-seconds: 10
      client:
        service-url:
          defaultZone: http://eureka1.server.com:8701/eureka/,http://eureka2.server.com:8702/eureka/,http://eureka3.server.com:8703/eureka/
    

    只设置ribbon的路由熔断,feign设置和ribbon相同。

    • Hystrix支持两个参数:
    • name:即HystrixCommand的名字
    • fallbackUri:fallback对应的uri,这里的uri仅支持forward:schemed

    1.3 创建FallBackController

    package spring.cloud.demo.spring.gateway.controller;
    
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class FallBackController {
    
        @GetMapping("/fallback")
        public String fallback() {
            return "Error:fallback";
        }
        
    }
    

    1.4 启动相关服务

    启动eureka-server、eureka-client、eureka-ribbon、spring-gateway相关服务,访问http://localhost:8100/ribbon/sayHello地址,页面显示结果如下:

    然后我们将eureka-ribbon服务停掉,刷新页面,返回结果如下:

    至此:熔断的简单配置实现就完成了,如需自定义熔断策略可以参考HystrixGatewayFilter的内容。

    限流

    Spring Cloud Gateway官方提供了RequestRateLimiterGatewayFilterFactory类,使用redis和lua脚本来实现令牌桶的方式。我们也可以基于Google Guava中的RateLimiter、Bucket4j、RateLimitJ来实现。本文将采用官方提供的方式来实现。

    1.1 增加pom相关依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
    </dependency>
    

    1.2 修改application.yml配置

    server:
      port: 8100
    spring:
      redis:
        host: localhost
        port: 6379
      application:
        name: spring-gateway
      cloud:
          gateway:
            discovery:
              locator:
                enabled: true # 开启通过服务中心的自动根据 serviceId 创建路由的功能
            default-filters:
              - My=true
            routes:
              - id: ribbon-route
                uri: lb://EUREKA-RIBBON
                order: 0
                predicates:
                  - Path=/ribbon/**
                filters:
                  - name: RequestRateLimiter
                    args:
                      key-resolver: '#{@ipKeyResolver}'
                      redis-rate-limiter.replenishRate: 200
                      redis-rate-limiter.burstCapacity: 400
                  - name: Hystrix
                    args:
                      name: fallback
                      fallbackUri: forward:/fallback
                  - StripPrefix=1 #去掉前缀,具体实现参考StripPrefixGatewayFilterFactory
                  - AddResponseHeader=X-Response-Default-Foo, Default-Bar
              - id: feign-route
                uri: lb://EUREKA-FEIGN
                order: 0
                predicates:
                  - Path=/feign/**
                filters:
                  - StripPrefix=1
                  - AddResponseHeader=X-Response-Default-Foo, Default-Bar
    
    eureka:
      instance:
        hostname: eureka1.server.com
        lease-renewal-interval-in-seconds: 5
        lease-expiration-duration-in-seconds: 10
      client:
        service-url:
          defaultZone: http://eureka1.server.com:8701/eureka/,http://eureka2.server.com:8702/eureka/,http://eureka3.server.com:8703/eureka/
    

    说明:

    • 1 增加redis相关配置
    • 2.1 -name: RequestRateLimiter, filter的名称,必须是RequestRateLimiter
    • 2.2 redis-rate-limiter.replenishRate: 允许用户每秒处理的请求个数
    • 2.3 redis-rate-limiter.burstCapacity: 令牌桶的容量,允许在一秒内完成的最大请求数
    • 2.4 key-resolver: 使用的Bean名称,规则为按名称引用Bean

    1.3 增加限流Bean

    package spring.cloud.demo.spring.gateway.config;
    
    import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import reactor.core.publisher.Mono;
    
    @Configuration
    public class BeanConfig {
    
        @Bean
        public KeyResolver ipKeyResolver() {
            return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName());
        }
    }
    

    这里设置的是ip的限流。

    1.4 启动相关服务

    首先启动redis服务,然后顺序启动eureka-server、eureka-client、eureka-ribbon、spring-gateway相关服务,访问http://localhost:8100/ribbon/sayHello。为了演示方便可以将redis-rate-limiter.replenishRate和redis-rate-limiter.burstCapacity参数设置成1和3,然后疯狂刷新页面可以看到有请求失败的情况(最好使用压测工具来演示)。同时我们还要打开redis的监控(monitor命令),可以看到redis的监控,如下:

    说明:redis中会有2个key,request_rate_limiter.{xxx}.timestamp和request_rate_limiter.{xxx}.tokens

    总结

    本文简单的实现了Gateway的熔断和限流。总体来说Spring Cloud Gateway提供的路由网关、过滤器、熔断、限流还是都比较简单,也非常灵活,可以根据自己的需求来自定义。

    代码地址

    gitHub地址


    《Srping Cloud 2.X小白教程》目录

    • 写作不易,转载请注明出处,喜欢的小伙伴可以关注公众号查看更多喜欢的文章,你的每一次查看就是对我最大的支持,你的点赞就是对我最大的鼓励。
    • 联系方式:4272231@163.com
  • 相关阅读:
    2020.10.23 19级training 补题报告
    2020.10.17 天梯赛练习 补题报告
    2020.10.16 19级training 补题报告
    2020.10.9 19级training 补题报告
    2020.10.10 天梯赛练习 补题报告
    2020.10.3 天梯赛练习 补题报告
    2020.10.2 19级training 补题报告
    第十届山东省ACM省赛复现补题报告
    VVDI Key Tool Plus Adds VW Passat 2015 Key via OBD
    Xhorse VVDI Prog Software V5.0.3 Adds Many MCUs
  • 原文地址:https://www.cnblogs.com/fengfujie/p/11820575.html
Copyright © 2011-2022 走看看