#590 improve Retry explanation
This commit is contained in:
parent
1886a6f969
commit
645fb20730
@ -8,16 +8,12 @@ tags:
|
|||||||
- Performance
|
- Performance
|
||||||
---
|
---
|
||||||
|
|
||||||
## Retry / resiliency
|
|
||||||
Enables an application to handle transient failures from external resources.
|
|
||||||
|
|
||||||
## Intent
|
## Intent
|
||||||
Transparently retry certain operations that involve communication with external
|
Transparently retry certain operations that involve communication with external resources, particularly over the
|
||||||
resources, particularly over the network, isolating calling code from the
|
network, isolating calling code from the retry implementation details.
|
||||||
retry implementation details.
|
|
||||||
|
|
||||||
## Explanation
|
## Explanation
|
||||||
The `Retry` pattern consists retrying operations on remote resources over the
|
Retry pattern consists retrying operations on remote resources over the
|
||||||
network a set number of times. It closely depends on both business and technical
|
network a set number of times. It closely depends on both business and technical
|
||||||
requirements: how much time will the business allow the end user to wait while
|
requirements: how much time will the business allow the end user to wait while
|
||||||
the operation finishes? What are the performance characteristics of the
|
the operation finishes? What are the performance characteristics of the
|
||||||
@ -30,11 +26,7 @@ Another concern is the impact on the calling code by implementing the retry
|
|||||||
mechanism. The retry mechanics should ideally be completely transparent to the
|
mechanism. The retry mechanics should ideally be completely transparent to the
|
||||||
calling code (service interface remains unaltered). There are two general
|
calling code (service interface remains unaltered). There are two general
|
||||||
approaches to this problem: from an enterprise architecture standpoint
|
approaches to this problem: from an enterprise architecture standpoint
|
||||||
(**strategic**), and a shared library standpoint (**tactical**).
|
(strategic), and a shared library standpoint (tactical).
|
||||||
|
|
||||||
*(As an aside, one interesting property is that, since implementations tend to
|
|
||||||
be configurable at runtime, daily monitoring and operation of this capability
|
|
||||||
is shifted over to operations support instead of the developers themselves.)*
|
|
||||||
|
|
||||||
From a strategic point of view, this would be solved by having requests
|
From a strategic point of view, this would be solved by having requests
|
||||||
be redirected to a separate intermediary system, traditionally an
|
be redirected to a separate intermediary system, traditionally an
|
||||||
@ -42,11 +34,26 @@ be redirected to a separate intermediary system, traditionally an
|
|||||||
a [Service Mesh](https://medium.com/microservices-in-practice/service-mesh-for-microservices-2953109a3c9a).
|
a [Service Mesh](https://medium.com/microservices-in-practice/service-mesh-for-microservices-2953109a3c9a).
|
||||||
|
|
||||||
From a tactical point of view, this would be solved by reusing shared libraries
|
From a tactical point of view, this would be solved by reusing shared libraries
|
||||||
like [Hystrix](https://github.com/Netflix/Hystrix)[1]. This is the type of
|
like [Hystrix](https://github.com/Netflix/Hystrix) (please note that *Hystrix* is a complete implementation of
|
||||||
solution showcased in the simple example that accompanies this *README*.
|
the [Circuit Breaker](https://java-design-patterns.com/patterns/circuit-breaker/) pattern, of which the Retry pattern
|
||||||
|
can be considered a subset of.). This is the type of solution showcased in the simple example that accompanies this
|
||||||
|
*README*.
|
||||||
|
|
||||||
In our hypothetical application, we have a generic interface for all
|
Real world example
|
||||||
operations on remote interfaces:
|
|
||||||
|
> Our application uses a service providing customer information. Once in a while the service seems to be flaky and can return errors or sometimes it just times out. To circumvent these problems we apply the retry pattern.
|
||||||
|
|
||||||
|
In plain words
|
||||||
|
|
||||||
|
> Retry pattern transparently retries failed operations over network.
|
||||||
|
|
||||||
|
[Microsoft documentation](https://docs.microsoft.com/en-us/azure/architecture/patterns/retry) says
|
||||||
|
|
||||||
|
> Enable an application to handle transient failures when it tries to connect to a service or network resource, by transparently retrying a failed operation. This can improve the stability of the application.
|
||||||
|
|
||||||
|
**Programmatic Example**
|
||||||
|
|
||||||
|
In our hypothetical application, we have a generic interface for all operations on remote interfaces.
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public interface BusinessOperation<T> {
|
public interface BusinessOperation<T> {
|
||||||
@ -54,8 +61,7 @@ public interface BusinessOperation<T> {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
And we have an implementation of this interface that finds our customers
|
And we have an implementation of this interface that finds our customers by looking up a database.
|
||||||
by looking up a database:
|
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public final class FindCustomer implements BusinessOperation<String> {
|
public final class FindCustomer implements BusinessOperation<String> {
|
||||||
@ -122,20 +128,12 @@ more importantly we did *not* instruct our `Retry` to ignore, then the operation
|
|||||||
would have failed immediately upon receiving the error, not matter how many
|
would have failed immediately upon receiving the error, not matter how many
|
||||||
attempts were left.
|
attempts were left.
|
||||||
|
|
||||||
<br/><br/>
|
|
||||||
|
|
||||||
[1] Please note that *Hystrix* is a complete implementation of the *Circuit
|
|
||||||
Breaker* pattern, of which the *Retry* pattern can be considered a subset of.
|
|
||||||
|
|
||||||
## Class diagram
|
## Class diagram
|
||||||

|

|
||||||
|
|
||||||
## Applicability
|
## Applicability
|
||||||
Whenever an application needs to communicate with an external resource,
|
Whenever an application needs to communicate with an external resource, particularly in a cloud environment, and if
|
||||||
particularly in a cloud environment, and if the business requirements allow it.
|
the business requirements allow it.
|
||||||
|
|
||||||
## Presentations
|
|
||||||
You can view Microsoft's article [here](https://docs.microsoft.com/en-us/azure/architecture/patterns/retry).
|
|
||||||
|
|
||||||
## Consequences
|
## Consequences
|
||||||
**Pros:**
|
**Pros:**
|
||||||
@ -150,4 +148,9 @@ You can view Microsoft's article [here](https://docs.microsoft.com/en-us/azure/a
|
|||||||
|
|
||||||
## Related Patterns
|
## Related Patterns
|
||||||
|
|
||||||
* [Circuit Breaker](https://martinfowler.com/bliki/CircuitBreaker.html)
|
* [Circuit Breaker](https://java-design-patterns.com/patterns/circuit-breaker/)
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
|
* [Retry pattern](https://docs.microsoft.com/en-us/azure/architecture/patterns/retry)
|
||||||
|
* [Cloud Design Patterns: Prescriptive Architecture Guidance for Cloud Applications](https://www.amazon.com/gp/product/1621140369/ref=as_li_tl?ie=UTF8&tag=javadesignpat-20&camp=1789&creative=9325&linkCode=as2&creativeASIN=1621140369&linkId=3e3f686af5e60a7a453b48adb286797b)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user