#circuit-breaker #ring-buffer #call #implemented #len #failure-rate

recloser

基于环形缓冲区实现的并发电路断路器

6 个版本 (3 个稳定版本)

1.1.1 2024 年 2 月 11 日
1.1.0 2022 年 7 月 27 日
1.0.0 2021 年 8 月 9 日
0.3.0 2020 年 9 月 22 日
0.1.0 2019 年 7 月 3 日

#68 in 并发

Download history 2421/week @ 2024-04-08 1680/week @ 2024-04-15 2776/week @ 2024-04-22 2923/week @ 2024-04-29 2222/week @ 2024-05-06 1567/week @ 2024-05-13 2492/week @ 2024-05-20 3613/week @ 2024-05-27 3095/week @ 2024-06-03 2877/week @ 2024-06-10 2787/week @ 2024-06-17 3595/week @ 2024-06-24 3230/week @ 2024-07-01 3849/week @ 2024-07-08 2343/week @ 2024-07-15 3260/week @ 2024-07-22

12,877 每月下载量

MIT 许可证

25KB
529

recloser ┃ 最新 文档

使用环形缓冲区实现的并发 电路断路器

Recloser 结构体提供了一个 call(...) 方法,用于封装可能失败的功能调用。当达到某些 failure_rate 时,它将积极拒绝这些调用,并在一段时间后再次允许它们。通过 AsyncRecloser 包装器,也提供了 call(...) 的未来感知版本。

API 主要基于 failsaferesilient4j 的环形缓冲区实现。

使用方法

Recloser 可以处于三种状态

  • State::Closed(RingBuffer(len)):初始的 Recloser 状态。在基于调用次数计算 failure_rate 之前,至少需要执行 len 次调用。在此之后,可能会发生从 State::Closed(_) 状态到 State::Open(_) 状态的转换。
  • State::Open(duration):在 duration 过去之前,所有调用都将返回 Err(Error::Rejected),然后发生从 State::Open(_) 状态到 State::HalfOpen(_) 状态的转换。
  • State::HalfOpen(RingBuffer(len)):在根据它计算failure_rate之前,至少需要执行len次调用。基于这个计算结果,状态将转换到State::Closed(_)State::Open(_)状态。

状态转换设置可以按以下方式自定义

use std::time::Duration;
use recloser::Recloser;

// Equivalent to Recloser::default()
let recloser = Recloser::custom()
   .error_rate(0.5)
   .closed_len(100)
   .half_open_len(10)
   .open_wait(Duration::from_secs(30))
   .build();

将危险函数调用包装起来以控制故障传播

use recloser::{Recloser, Error};

// Performs 1 call before calculating failure_rate
let recloser = Recloser::custom().closed_len(1).build();

let f1 = || Err::<(), usize>(1);

// First call, just recorded as an error
let res = recloser.call(f1);
assert!(matches!(res, Err(Error::Inner(1))));

// Now also computes failure_rate, that is 100% here
// Will transition to State::Open afterward
let res = recloser.call(f1);
assert!(matches!(res, Err(Error::Inner(1))));

let f2 = || Err::<(), i64>(-1);

// All calls are rejected (while in State::Open)
let res = recloser.call(f2);
assert!(matches!(res, Err(Error::Rejected)));

还可以根据调用丢弃一些错误。这种行为由ErrorPredicate<E>trait控制,它已经为所有Fn(&E) -> bool实现了。

use recloser::{Recloser, Error};

let recloser = Recloser::default();

let f = || Err::<(), usize>(1);

// Custom predicate that doesn't consider usize values as errors
let p = |_: &usize| false;

// Will not record resulting Err(1) as an error
let res = recloser.call_with(p, f);
assert!(matches!(res, Err(Error::Inner(1))));

包装返回Future的函数需要使用一个AsyncRecloser,它只是包装了一个普通的Recloser

use std::future;
use recloser::{Recloser, Error, AsyncRecloser};

let recloser = AsyncRecloser::from(Recloser::default());

let future = future::ready::<Result<(), usize>>(Err(1));
let future = recloser.call(future);

性能

Recloserfailsafe::CircuitBreaker的基准测试

  • 单线程工作负载:相同的性能
  • 多线程工作负载:Recloser10倍更好的性能
recloser_simple         time:   [355.17 us 358.67 us 362.52 us]
failsafe_simple         time:   [403.47 us 406.90 us 410.29 us]
recloser_concurrent     time:   [668.44 us 674.26 us 680.48 us]
failsafe_concurrent     time:   [11.523 ms 11.613 ms 11.694 ms]

这些基准测试是在一个Intel Core i7-6700HQ @ 8x 3.5GHz CPU上运行的。

依赖项

~0.6–1MB
~22K SLoC