美文网首页vertx
Vertx - RollingCounter

Vertx - RollingCounter

作者: pjqq | 来源:发表于2019-08-25 09:48 被阅读0次

源码坐标:package io.vertx.circuitbreaker.impl.CircuitBreakerImpl中内部类,是断路器Circuit Breaker中的循环计数器。
使用场景:Circuit Breaker通过统计时间窗口内的请求失败次数,如果超出阈值,则判定请求对象已无效,给予“熔断”。RollingCounter承担主要功能。

1.CircuitBreakerOptions设定阈值。

private static final int DEFAULT_FAILURES_ROLLING_WINDOW = 10000;
private long failuresRollingWindow = DEFAULT_FAILURES_ROLLING_WINDOW;

public CircuitBreakerOptions setFailuresRollingWindow(long failureRollingWindow) {
    this.failuresRollingWindow = failureRollingWindow;
    return this;
  }

2.创建失败循环计数。

this.rollingFailures = new RollingCounter(options.getFailuresRollingWindow() / 1000, TimeUnit.SECONDS);

3.RollingCounter

  public static class RollingCounter {
    private Map<Long, Long> window;
    private long timeUnitsInWindow;
    private TimeUnit windowTimeUnit;

    public RollingCounter(long timeUnitsInWindow, TimeUnit windowTimeUnit) {
      this.windowTimeUnit = windowTimeUnit;
      //创建一个有序Map,容量为时间区间,比如传入100,容量为101
      //用来容纳时间区间内的次数
      //---其实就是时间窗口
      this.window = new LinkedHashMap<>((int) timeUnitsInWindow + 1);
      this.timeUnitsInWindow = timeUnitsInWindow;
    }

    public void increment() {
      //记录一次调用
      long timeSlot = windowTimeUnit.convert(System.currentTimeMillis(), TimeUnit.MILLISECONDS);
      Long current = window.getOrDefault(timeSlot, 0L);
      window.put(timeSlot, ++current);
      //超出容量,删除最早那条
      //---维持窗口大小
      if (window.size() > timeUnitsInWindow) {
        Iterator<Long> iterator = window.keySet().iterator();
        if (iterator.hasNext()) {
          window.remove(iterator.next());
        }
      }
    }

    public long count() {
      //统计时间区间内调用次数  
      //---判定是否可以熔断
      long windowStartTime = windowTimeUnit.convert(System.currentTimeMillis() - windowTimeUnit.toMillis(timeUnitsInWindow), TimeUnit.MILLISECONDS);
      return window.entrySet().stream().filter(entry -> entry.getKey() >= windowStartTime).mapToLong(entry -> entry.getValue()).sum();
    }

    public void reset() {
      window.clear();
    }
  }

4.当断则断

  private synchronized void incrementFailures() {
    rollingFailures.increment();
    if (rollingFailures.count() >= options.getMaxFailures()) {
      if (state != CircuitBreakerState.OPEN) {
        open();
      } 
    }
  }

*LinkedHashMap简单理解为有顺序的HashMap,可以同时兼顾查值与按顺序删除操作,非常契合时间窗口的场景。

相关文章

  • Vertx - RollingCounter

    源码坐标:package io.vertx.circuitbreaker.impl.CircuitBreakerI...

  • Vertx

    背景 对于vertx框架,最基础的组件就是vertx,几乎所有功能都是通过vertx实现。 vertx聚合了网络通...

  • Vertx

    Vertx

  • vertx架构

    对于部署标准模式verticle,vertx的架构如下: 对于部署worker模式verticle,vertx的架...

  • 因为使用了Vertx CodeGen 导致lombok无法正常工

    因为使用了Vertx CodeGen 导致lombok无法正常工作解决方案:放弃使用 Vertx CodeGen

  • Context

    背景 在vertx框架中,核心概念是verticle,通过vertx可以部署多个verticle,且verticl...

  • vertx实践二——基于EventBus的交互demo

    1.代码展示 第一个vertx服务启动类 第一个vertx服务verticle 第二个vertx服务启动类 第二个...

  • vertx

    Vert.x保证同一个普通Verticle(也就是EventLoop Verticle,非Worker Verti...

  • Verticle

    背景 verticle相当于1个执行模块,是vertx的部署单元。 vertx可以部署多个verticle,且ve...

  • websocket开发中遇到的伪技术问题

    vertx是一个轻量,灵活的后端框架,最近在使用vertx时使用了它的websocket,对于websocket相...

网友评论

    本文标题:Vertx - RollingCounter

    本文链接:https://www.haomeiwen.com/subject/enqhectx.html