序
本文主要研究下resilience4j的基本功能
maven
<dependency> <groupId>io.github.resilience4j</groupId> <artifactId>resilience4j-circuitbreaker</artifactId> <version>0.13.0</version> </dependency> <dependency> <groupId>io.github.resilience4j</groupId> <artifactId>resilience4j-ratelimiter</artifactId> <version>0.13.0</version> </dependency> <dependency> <groupId>io.github.resilience4j</groupId> <artifactId>resilience4j-retry</artifactId> <version>0.13.0</version> </dependency> <dependency> <groupId>io.github.resilience4j</groupId> <artifactId>resilience4j-bulkhead</artifactId> <version>0.13.0</version> </dependency> <dependency> <groupId>io.github.resilience4j</groupId> <artifactId>resilience4j-circularbuffer</artifactId> <version>0.13.0</version> </dependency> <dependency> <groupId>io.github.resilience4j</groupId> <artifactId>resilience4j-timelimiter</artifactId> <version>0.13.0</version> </dependency>
CircuitBreaker
@Test public void testCircuitBreaker(){ // Create a CircuitBreaker (use default configuration) CircuitBreakerConfig circuitBreakerConfig = CircuitBreakerConfig .custom() .enableAutomaticTransitionFromOpenToHalfOpen() .build(); CircuitBreaker circuitBreaker = CircuitBreaker .of("backendName",circuitBreakerConfig); String result = circuitBreaker.executeSupplier(() -> backendService.doSomethingWithArgs("world")); System.out.println(result); }
CircuitBreaker主要是实现针对接口异常的断路统计以及断路处理
Timelimiter
@Test public void testTimelimiter(){ ExecutorService executorService = Executors.newSingleThreadExecutor(); TimeLimiterConfig config = TimeLimiterConfig.custom() .timeoutDuration(Duration.ofMillis(600)) .cancelRunningFuture(true) .build(); TimeLimiter timeLimiter = TimeLimiter.of(config); Supplier<Future<String>> futureSupplier = () -> { return executorService.submit(backendService::doSomethingThrowException); }; Callable<String> restrictedCall = TimeLimiter.decorateFutureSupplier(timeLimiter,futureSupplier); Try.of(restrictedCall::call) .onFailure(throwable -> System.out.println("We might have timed out or the circuit breaker has opened.")); }
主要是实现超时的控制
Bulkhead
/** * A Bulkhead can be used to limit the amount of parallel executions */ @Test public void testBulkhead(){ Bulkhead bulkhead = Bulkhead.of("test", BulkheadConfig.custom() .maxConcurrentCalls(1) .build()); Supplier<String> decoratedSupplier = Bulkhead.decorateSupplier(bulkhead, backendService::doSomethingSlowly); IntStream.rangeClosed(1,2) .parallel() .forEach(i -> { String result = Try.ofSupplier(decoratedSupplier) .recover(throwable -> "Hello from Recovery").get(); System.out.println(result); }); }
Bulkhead目前来看是用来控制并行(
parallel
)调用的次数
RateLimiter
@Test public void testRateLimiter(){ // Create a custom RateLimiter configuration RateLimiterConfig config = RateLimiterConfig.custom() .timeoutDuration(Duration.ofMillis(100)) .limitRefreshPeriod(Duration.ofSeconds(1)) .limitForPeriod(1) .build(); // Create a RateLimiter RateLimiter rateLimiter = RateLimiter.of("backendName", config); // Decorate your call to BackendService.doSomething() Supplier<String> restrictedSupplier = RateLimiter .decorateSupplier(rateLimiter, backendService::doSomething); IntStream.rangeClosed(1,5) .parallel() .forEach(i -> { Try<String> aTry = Try.ofSupplier(restrictedSupplier); System.out.println(aTry.isSuccess()); }); }
用来做流控
Fallback
@Test public void testFallback(){ // Execute the decorated supplier and recover from any exception String result = Try.ofSupplier(() -> backendService.doSomethingThrowException()) .recover(throwable -> "Hello from Recovery").get(); System.out.println(result); } @Test public void testCircuitBreakerAndFallback(){ CircuitBreaker circuitBreaker = CircuitBreaker.ofDefaults("backendName"); Supplier<String> decoratedSupplier = CircuitBreaker .decorateSupplier(circuitBreaker, backendService::doSomethingThrowException); String result = Try.ofSupplier(decoratedSupplier) .recover(throwable -> "Hello from Recovery").get(); System.out.println(result); }
fallback基本上是高可用操作的标配
Retry
@Test public void testRetry(){ CircuitBreaker circuitBreaker = CircuitBreaker.ofDefaults("backendName"); // Create a Retry with at most 3 retries and a fixed time interval between retries of 500ms Retry retry = Retry.ofDefaults("backendName"); // Decorate your call to BackendService.doSomething() with a CircuitBreaker Supplier<String> decoratedSupplier = CircuitBreaker .decorateSupplier(circuitBreaker, backendService::doSomething); // Decorate your call with automatic retry decoratedSupplier = Retry .decorateSupplier(retry, decoratedSupplier); // Execute the decorated supplier and recover from any exception String result = Try.ofSupplier(decoratedSupplier) .recover(throwable -> "Hello from Recovery").get(); System.out.println(result); }
retry用来控制重试
小结
resilience4j是一款受hystrix启发的容错组件,提供了如下几款核心组件:
- resilience4j-circuitbreaker: Circuit breaking
- resilience4j-ratelimiter: Rate limiting
- resilience4j-bulkhead: Bulkheading
- resilience4j-retry: Automatic retrying (sync and async)
- resilience4j-cache: Response caching 这里主要演示了关于circuitbreaker、ratelimiter、bulkhead、retry以及timelimiter。其特色就是使用装饰者模式,可以多个功能组合在一起。其他的话,timelimiter的使用比起hystrix稍微费劲些。