SpringCloud系列——限流、熔断、降级

本文聚焦分布式环境下服务的高可用保护机制,记录了限流、熔断、降级的实现处理。采用令牌桶限流法,在SpringCloud分布式下可在公共地方维护令牌桶。通过yml配置开启Hystrix熔断功能,调用服务异常时可采用重连、返回提示、调用备用服务等降级方式。代码已开源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  前言

  分布式环境下,服务直接相互调用,一个复杂的业务可能要调用多个服务,例如A -> B -> C -> D,当某个服务出现异常(调用超时、调用失败等)将导致整个流程阻塞崩溃,严重的整个系统都会崩掉,为了实现高可用,必要的保护机制必不可少

  本文记录限流、熔断、降级的实现处理

 

  限流

  我们采用令牌桶限流法,并自己实现一个简单令牌桶限流

  有个任务线程以恒定速率向令牌桶添加令牌

  一个请求会消耗一个令牌,令牌桶里的令牌大于0,才会放行,反正不允许通过

/**
 * 简单的令牌桶限流
 */
public class RateLimiter {

    /**
     * 桶的大小
     */
    private Integer limit;

    /**
     * 桶当前的token
     */
    private static Integer tokens = 0;

    /**
     * 构造参数
     */
    public RateLimiter(Integer limit, Integer speed){
        //初始化桶的大小,且桶一开始是满的
        this.limit = limit;
        tokens = this.limit;

        //任务线程:每秒新增speed个令牌
        new Thread(() ->{
            while (true){
                try {
                    Thread.sleep(1000L);

                    int newTokens = tokens + speed;
                    if(newTokens > limit){
                        tokens = limit;
                        System.out.println("令牌桶满了!!!");
                    }else{
                        tokens = newTokens;
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    /**
     * 根据令牌数判断是否允许执行,需要加锁
     */
    public synchronized boolean execute() {
        if (tokens > 0) {
            tokens = tokens - 1;
            return true;
        }
        return false;
    }
}

  main简单测试

    public static void main(String[] args) {
        //令牌桶限流:峰值每秒可以处理10个请求,正常每秒可以处理3个请求
        RateLimiter rateLimiter = new RateLimiter(10, 3);

        //模拟请求
        while (true){
            //在控制台输入一个值按回车,相对于发起一次请求
            Scanner scanner = new Scanner(System.in);
            scanner.next();

            //令牌桶返回true或者false
            if(rateLimiter.execute()){
                System.out.println("允许访问");
            }else{
                System.err.println("禁止访问");
            }
        }
    }

  在SpringCloud分布式下实现限流,需要把令牌桶的维护放到一个公共的地方,比如Zuul路由,当然也可以同时针对具体的每个服务进行单独限流

  另外,guava里有现成的基于令牌桶的限流实现,引入

        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>26.0-jre</version>
        </dependency>

  具体用法这里就不阐述了

 

  我们找出之前的springcloud项目,在zuul-server中的AccessFilter过滤器进行限流,其他的都不变,只需要做如下修改

  PS:我这里为了方便测试,调小了令牌桶的大小,跟速率,正常情况下要服务器的承受能力来定

/**
 * Zuul过滤器,实现了路由检查
 */
public class AccessFilter extends ZuulFilter {
    //令牌桶限流:峰值每秒可以处理10个请求,正常每秒可以处理3个请求
//PS:我这里为了方便测试,调小了令牌桶的大小,跟速率,正常情况下按服务器的承受能力来定
private RateLimiter rateLimiter = new RateLimiter(2, 1); //业务不变,省略其他代码... /** * 过滤器的具体逻辑 */ @Override public Object run() { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); HttpServletResponse response = ctx.getResponse(); //限流 if(!rateLimiter.execute()){ try { ctx.setSendZuulResponse(false); ctx.setResponseStatusCode(200); //直接写入浏览器 response.setContentType("text/html;charset=UTF-8"); PrintWriter writer = response.getWriter(); writer.println("系统繁忙,请稍后在试!<br/>System busy, please try again later!"); writer.flush();return null; } catch (Exception e) { e.printStackTrace(); } } //业务不变,省略其他代码.. } }

  按照我们设置的值,一秒能处理一个请求,峰值一秒能处理两个请求,下面疯狂刷新进行测试

 

 

  熔断

  yml配置开启Hystrix熔断功能,进行容错处理

feign:
  hystrix:
    enabled: true

  设置Hystrix的time-out时间

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 5000 #毫秒
      #或者设置从不超时
      #timeout:
      #  enabled: false

  在使用Feign调用服务提供者时配置@FeignClient的 fallback,进行容错处理(服务提供者发生异常),如果需要获取到异常信息,则要配置fallbackFactory<T>

@FeignClient(name = "sso-server", path = "/",/*fallback = SsoFeign.SsoFeignFallback.class,*/fallbackFactory = SsoFeign.SsoFeignFallbackFactory.class)

 

    /**
     * 容错处理(服务提供者发生异常,将会进入这里)
     */
    @Component
    public class SsoFeignFallback implements SsoFeign {

        @Override
        public Boolean hasKey(String key) {
            System.out.println("调用sso-server失败,进行SsoFeignFallback.hasKey处理:return false;");
            return false;
        }
    }

 

    /**
     * 只打印异常,容错处理仍交给 SsoFeignFallback
     */
    @Component
    public class SsoFeignFallbackFactory implements FallbackFactory<SsoFeign> {
        private final SsoFeignFallback ssoFeignFallback;

        public SsoFeignFallbackFactory(SsoFeignFallback ssoFeignFallback) {
            this.ssoFeignFallback = ssoFeignFallback;
        }

        @Override
        public SsoFeign create(Throwable cause) {
            cause.printStackTrace();
            return ssoFeignFallback;
        }
    }

 

  FallbackFactory也可以这样写

    /**
     * 容错处理
     */
@Component
public class SsoFeignFallbackFactory implements FallbackFactory<SsoFeign> { @Override public SsoFeign create(Throwable cause) { //打印异常 cause.printStackTrace(); return new SsoFeign() { @Override public Boolean hasKey(String key) { System.out.println("调用sso-server失败:return false;"); return false; } }; } }

 

  因为我们没有启动Redis,报错,但我们进行容错处理,所以还是返回了false

 

 

  降级

   当调用服务发送异常,容错处理的方式有多种,我们可以:

  1、重连,比如服务进行了限流,本次连接被限制,重连一次或N次就可以得到数据

  2、直接返回一个友好提示

  3、降级调用备用服务、返回缓存的数据等

 

  后记

  降级也可以叫做“备胎计划”...

 

  代码开源

  代码已经开源、托管到我的GitHub、码云:

  GitHub:https://github.com/huanzi-qch/springCloud

  码云:https://gitee.com/huanzi-qch/springCloud

转载于:https://www.cnblogs.com/huanzi-qch/p/11053061.html

在Spring Cloud中,熔断降级限流是通过使用Hystrix来实现的。熔断机制中涉及了三种熔断状态:熔断关闭状态、熔断开启状态和半熔断状态。当服务访问正常时,熔断器处于关闭状态,服务调用方可以正常地进行服务调用。当接口调用出错比率达到一个阈值时,熔断器会进入熔断开启状态,后续对该服务的调用都会被切断,熔断器会执行本地的降级方法。在熔断开启一段时间之后,熔断器会进入半熔断状态,尝试恢复服务调用方对服务的调用,允许部分请求调用该服务,并监控其调用成功率。如果成功率达到预期,则说明服务已恢复正常,熔断器进入关闭状态;如果成功率仍旧很低,则重新进入熔断开启状态。\[1\] 在Spring Cloud中,可以通过使用Hystrix来实现服务降级熔断限流。服务降级是指在服务不可用或响应时间过长时,提供一个备用的响应或返回缺省值,以保证系统的可用性。熔断是指在服务出现故障或异常时,断开对该服务的调用,避免对整个系统的影响。限流是指对服务的访问进行限制,防止系统被过多的请求压垮。\[2\] 在Spring Cloud中,可以通过在主启动类上添加@EnableCircuitBreaker注解来激活熔断器功能。同时,可以使用@HystrixCommand注解来标记需要进行熔断降级的方法。在方法中,可以通过定义fallback方法来实现服务降级的逻辑。\[3\] #### 引用[.reference_title] - *1* *2* *3* [SpringCloud学习——Histrix服务限流降级熔断](https://blog.youkuaiyun.com/KIMTOU/article/details/125359690)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值