Skip to main content

Vert.x Circuit Breaker

Vert.x断路器是Vert.x的断路器模式的实现. 它跟踪故障次数,并达到阈值时断开电路 . (可选)执行回退.

支持的故障有:

  • 您的代码在Future报告的故障

  • 您的代码引发的异常

  • 未完成的期货(超时)

断路器保护的操作旨在非阻塞且异步的,以便从Vert.x执行模型中受益.

Using the vert.x circuit breaker

要使用Vert.x断路器,请将以下依赖项添加到构建描述符的" 依赖项"部分:

  • Maven(在您的pom.xml ):

<dependency>
 <groupId>io.vertx</groupId>
 <artifactId>vertx-circuit-breaker</artifactId>
 <version>3.8.4</version>
</dependency>
  • Gradle(在您的build.gradle文件中):

compile 'io.vertx:vertx-circuit-breaker:3.8.4'

Using the circuit breaker

要使用断路器,您需要:

  1. 创建具有所需配置的断路器(超时,断开电路之前的故障数)

  2. 使用断路器执行一些代码

重要提示 :请勿在每次通话时都重新创建断路器. 断路器是稳定的实体. 建议将断路器实例存储在一个字段中.

这是一个例子:

require 'vertx-circuit-breaker/circuit_breaker'
breaker = VertxCircuitBreaker::CircuitBreaker.create("my-circuit-breaker", vertx, {
  'maxFailures' => 5,
  'timeout' => 2000,
  'fallbackOnFailure' => true,
  'resetTimeout' => 10000
})

# ---
# Store the circuit breaker in a field and access it as follows
# ---

breaker.execute() { |future|
  # some code executing with the breaker
  # the code reports failures or success on the given future.
  # if this future is marked as failed, the breaker increased the
  # number of failures
}.set_handler() { |ar_err,ar|
  # Get the operation result.
}

执行的块接收Future对象作为参数,以表示操作的成功或失败以及结果. 例如,在以下示例中,结果是REST端点调用的输出:

require 'vertx-circuit-breaker/circuit_breaker'
breaker = VertxCircuitBreaker::CircuitBreaker.create("my-circuit-breaker", vertx, {
  'maxFailures' => 5,
  'timeout' => 2000
})

# ---
# Store the circuit breaker in a field and access it as follows
# ---

breaker.execute() { |future|
  vertx.create_http_client().get_now(8080, "localhost", "/") { |response|
    if (response.status_code() != 200)
      future.fail("HTTP error")
    else
      response.exception_handler(&future.method(:fail)).body_handler() { |buffer|
        future.complete(buffer.to_string())
      }
    end
  }
}.set_handler() { |ar_err,ar|
  # Do something with the result
}

使用以下命令提供操作结果:

  • 调用execute方法时返回Future

  • 调用executeAndReport方法时提供Future

(可选)您可以提供回退,该回退在电路断开时执行:

require 'vertx-circuit-breaker/circuit_breaker'
breaker = VertxCircuitBreaker::CircuitBreaker.create("my-circuit-breaker", vertx, {
  'maxFailures' => 5,
  'timeout' => 2000
})

# ---
# Store the circuit breaker in a field and access it as follows
# ---

breaker.execute_with_fallback(lambda { |future|
  vertx.create_http_client().get_now(8080, "localhost", "/") { |response|
    if (response.status_code() != 200)
      future.fail("HTTP error")
    else
      response.exception_handler(&future.method(:fail)).body_handler() { |buffer|
        future.complete(buffer.to_string())
      }
    end
  }
}, lambda { |v|
  # Executed when the circuit is opened
  return "Hello"
}).set_handler() { |ar_err,ar|
  # Do something with the result
}

每当电路isFallbackOnFailure或启用isFallbackOnFailure时,都会调用fallback. 设置后备时,结果将使用后备功能的输出. fallback函数将Throwable对象作为参数,并返回期望类型的对象.

还可以直接在CircuitBreaker对象上设置后备:

require 'vertx-circuit-breaker/circuit_breaker'
breaker = VertxCircuitBreaker::CircuitBreaker.create("my-circuit-breaker", vertx, {
  'maxFailures' => 5,
  'timeout' => 2000
}).fallback(lambda { |v|
  # Executed when the circuit is opened.
  return "hello"
})

breaker.execute() { |future|
  vertx.create_http_client().get_now(8080, "localhost", "/") { |response|
    if (response.status_code() != 200)
      future.fail("HTTP error")
    else
      response.exception_handler(&future.method(:fail)).body_handler() { |buffer|
        future.complete(buffer.to_string())
      }
    end
  }
}

Retries

您还可以指定在maxRetries失败之前断路器应多久尝试一次代码. 如果将此值设置为大于0的值,则代码将执行几次,直到最后一次执行失败. 如果代码在重试之一中成功,则您的处理程序将收到通知,并且所有剩余的重试都将被跳过. 仅在电路闭合时才支持重试.

请注意,例如,如果将maxRetries设置为2,则可能会调用3次操作:初始尝试和2次重试.

默认情况下,重试之间的超时设置为0,这意味着重试将一次又一次地执行,不会有任何延迟. 但是,这将导致被调用服务的负载增加,并可能延迟其恢复. 为了缓解此问题,建议延迟执行重试. retryPolicy方法可用于指定重试策略. 重试策略是一项功能,该函数将重试计数作为单个参数接收,并在执行重试之前以毫秒为单位返回超时,并允许实施更复杂的策略,例如带抖动的指数补偿. 以下是重试超时的示例,该超时随着每个重试计数线性增长:

require 'vertx-circuit-breaker/circuit_breaker'
breaker = VertxCircuitBreaker::CircuitBreaker.create("my-circuit-breaker", vertx, {
  'maxFailures' => 5,
  'maxRetries' => 5,
  'timeout' => 2000
}).open_handler() { |v|
  puts "Circuit opened"
}.close_handler() { |v|
  puts "Circuit closed"
}.retry_policy(lambda { |retryCount|
  retryCount * 100
})

breaker.execute() { |future|
  vertx.create_http_client().get_now(8080, "localhost", "/") { |response|
    if (response.status_code() != 200)
      future.fail("HTTP error")
    else
      # Do something with the response
      future.complete()
    end
  }
}

Callbacks

您还可以配置在电路打开或关闭时调用的回调:

require 'vertx-circuit-breaker/circuit_breaker'
breaker = VertxCircuitBreaker::CircuitBreaker.create("my-circuit-breaker", vertx, {
  'maxFailures' => 5,
  'timeout' => 2000
}).open_handler() { |v|
  puts "Circuit opened"
}.close_handler() { |v|
  puts "Circuit closed"
}

breaker.execute() { |future|
  vertx.create_http_client().get_now(8080, "localhost", "/") { |response|
    if (response.status_code() != 200)
      future.fail("HTTP error")
    else
      # Do something with the response
      future.complete()
    end
  }
}

当断路器决定尝试复位(半断开状态)时,也会通知您. 您可以使用halfOpenHandler注册这样的回调.

Event bus notification

每次电路状态改变时,事件都会在事件总线上发布. 发送事件的地址可通过notificationAddress配置. 如果将null传递给此方法,则禁用通知. 默认情况下,使用的地址是vertx.circuit-breaker .

每个事件都包含一个具有以下内容的Json对象:

  • state :新的断路器状态( OPENCLOSEDHALF_OPEN

  • name :断路器的名称

  • failures次数:失败次数

  • node : the identifier of the node (local if Vert.x is not running in cluster mode)

The half-open state

当电路"断开"时,对断路器的调用将立即失败,而无需尝试执行实际操作. 经过一段适当的时间(从resetTimeout配置resetTimeout ,断路器决定操作有机会成功,因此进入half-open状态.在此状态下,允许对断路器的下一次调用执行危险操作.如果调用成功,断路器复位,并返回到closed状态,准备更多的常规操作.但是,如果这项试验调用失败,断路器返回到open状态,直到另一个超时时间.

Reported exceptions

备用广告收到以下消息:

Pushing circuit breaker metrics to the Hystrix Dashboard

Netflix Hystrix带有一个仪表板,用于显示断路器的当前状态. Vert.x断路器可以发布其指标,以便被此Hystrix仪表板使用. Hystrix仪表板需要SSE流来发送指标. 该流由HystrixMetricHandler Vert.x Web处理程序提供:

require 'vertx-circuit-breaker/circuit_breaker'
require 'vertx-web/router'
require 'vertx-circuit-breaker/hystrix_metric_handler'
# Create the circuit breaker as usual.
breaker = VertxCircuitBreaker::CircuitBreaker.create("my-circuit-breaker", vertx)
breaker2 = VertxCircuitBreaker::CircuitBreaker.create("my-second-circuit-breaker", vertx)

# Create a Vert.x Web router
router = VertxWeb::Router.router(vertx)
# Register the metric handler
router.get("/hystrix-metrics").handler(&VertxCircuitBreaker::HystrixMetricHandler.create(vertx).method(:handle))

# Create the HTTP server using the router to dispatch the requests
vertx.create_http_server().request_handler(&router.method(:handle)).listen(8080)

在Hystrix仪表板中,配置流URL,例如: http://localhost:8080/metrics . 仪表板现在使用来自Vert.x断路器的指标.

注意,度量是由Vert.x Web处理程序使用事件总线通知收集的. 如果不使用默认的通知地址,则在创建指标处理程序时需要传递它.

by  ICOPY.SITE