Resilience4j is a lightweight, easy-to-use fault-tolerant library inspired by Netflix Hystrix, but designed for Java 8 and functional programming. Lightweight, because the library only uses Vavr, it does not have any other external library dependencies. In contrast, Netflix Hystrix has a compile dependency on Archaius, which has more external library dependencies such as Guava and Apache Commons.

Resilience4j provides high-order functions (decorators) to enhance any functional interface, lambda expression, or method reference, including circuit breakers, rate limiters, retries, or bulkheads. You can use more than one decorator on any function interface, lambda expression, or method reference. The advantage is that you can choose the decorators you want without needing anything else.

With Resilience4j, you don’t have to go all out, you can choose what you need.

Resilience4j. Readme. IO/docs/gettin…

An overview of

This paper will introduce four fault tolerance mechanisms in Resilience4J. However, due to the universality of the principle of the fault tolerance mechanism, these fault tolerance mechanisms can also exist independently from The Resilience4J (you can completely code them or use other similar third-party libraries. Like Netflix Hystrix). The concepts and principles of Bulkhead, CircuitBreaker, RateLimiter and Retry mechanism will be explained by legend below.

Bulkhead

Resilience4j provides two implementations of bulkhead patterns that can be used to limit the number of concurrent executions:

  • SemaphoreBulkhead (Semaphore bulkhead, default), based on Semaphore implementation in Java concurrent library.
  • FixedThreadPoolBulkhead, which uses a bounded queue and a fixed thread pool.

SemaphoreBulkhead should work well on a variety of threads and I/O models. It is semaphore based and, unlike Hystrix, does not provide a “shadow” thread pool option. Depends on the client to ensure that the correct thread pool size will be consistent with the bulkhead configuration.

SemaphoreBulkhead

👆 Original address:SemaphoreBulkhead

As shown in the figure above, a request that enters the system when a semaphore is left will directly acquire the semaphore and begin business processing. When the semaphore is fully occupied, subsequent requests will enter the blocking state. SemaphoreBulkhead provides a blocking timer. If the blocked requests cannot obtain the semaphore within the blocking time, the system will reject these requests. If the request gets the semaphore within the blocking timer, it gets the semaphore directly and executes the corresponding business processing.

FixedThreadPoolBulkhead

👆 Original address:FixedThreadPoolBulkhead

Similar to SemaphoreBulkhead, FixedThreadPoolBulkhead is used to limit the number of concurrent executions, but their implementation principles are different and their performance is slightly different. FixedThreadPoolBulkhead uses a fixed thread pool and a wait queue to implement the bulkhead. When there is idle in the thread pool, the requests coming into the system will either go directly to the thread pool to start a new thread or use the idle thread to process the request. When the thread pool is not idle, subsequent requests will be queued. If the queue is still empty, subsequent requests will be rejected. When a request in a queue is waiting for the thread pool to become idle, it enters the thread pool for business processing.

One obvious difference between FixedThreadPoolBulkhead and SemaphoreBulkhead is that FixedThreadPoolBulkhead has no concept of blocking, while SemaphoreBulkhead has no limit on queue capacity.

RateLimiter

👆 Original address:RateLimiter

The RateLimiter is designed to prevent a sudden overload of requests from overwhelming the system. RateLimiter uses the concept of a refresh cycle to limit the maximum number of requests that can be processed in a fixed refresh cycle. If the number of requests has reached the maximum in a certain period, the following requests in that period will be blocked. If a new flush period is opened within the maximum blocking time, the blocked requests will be processed in a new period. If a new flush cycle is not enabled within the maximum block timer, requests that exceed the block timer will be rejected outright.

CircuitBreaker

👆 Original address:CircuitBreaker

Circuitbreakers are more complex than the previous circuit breakers. A CircuitBreaker usually has three states (CLOSE, OPEN, HALF_OPEN) and records the current request success rate or slow rate through a window of time or quantity. According to these indexes, the correct fault-tolerant response can be made.

If the CircuitBreaker status is set to CLOSE, all requests sent by the client will enter the server system normally. The CircuitBreaker will calculate the exception rate (failure rate or slow rate) of all requests in the window before the current request. If the exception rate is lower than the expected value, the system will continue to process the following requests normally. When the exception rate is not lower than the expected value, the server enters the OPEN state and temporarily rejects all requests. After a cooling period (custom configuration), the server automatically enters the HALF_OPEN state. In the half-open state, the server tries to accept a certain number of requests (custom configuration). If the exception rate of a certain number of requests is lower than expected, the server recovers the CLOSE state and processes the requests normally. If the anomaly rate is still higher than expected, it will continue to fall back to the OPEN state.

Retry

👆 Original address:Retry

The retry mechanism is simple. When the server processes an exception request from a client, the server enables the retry mechanism. During the retry, the server retries service logic processing at intervals. If the service is successfully processed within the maximum number of retries, the retry is stopped and the processing is successful. If the service logic is still abnormal within the maximum number of retries, the system rejects the request.

conclusion

This paper introduces several commonly used fault tolerance mechanisms. It is better to directly remove the resilience4J than the fault tolerance mechanism in The Resilience4j, because it can be seen that these mechanisms are not only from a library or related to a specific library, but also a design concept, and its universality should be cross-language. Furthermore, while this article has only covered these fault-tolerant mechanisms, how you use them depends entirely on your business scenario and architectural design. You can even use them in random combinations, and it doesn’t really matter which mechanic these combinations will look like, depending on your technical/business environment.


🌟 🌟 🌟 🌟 🌟 🌟 🌟 🌟 🌟 🌟 🌟 🌟 🌟 🌟 🌟 🌟 🌟 🌟

Welcome to my blog:blog.dongxishaonian.tech

Pay attention to the author’s public account, push all kinds of original/high quality technical articles ⬇️