https://github.com/vertx-howtos/resilience4j-howto
Using Resilience4j with Vert.x
https://github.com/vertx-howtos/resilience4j-howto
circuit-breaker howto resilience4j vertx
Last synced: 13 days ago
JSON representation
Using Resilience4j with Vert.x
- Host: GitHub
- URL: https://github.com/vertx-howtos/resilience4j-howto
- Owner: vertx-howtos
- License: apache-2.0
- Created: 2023-07-10T13:01:27.000Z (almost 2 years ago)
- Default Branch: master
- Last Pushed: 2024-12-04T13:55:12.000Z (5 months ago)
- Last Synced: 2025-03-23T21:22:34.764Z (about 1 month ago)
- Topics: circuit-breaker, howto, resilience4j, vertx
- Language: Java
- Homepage:
- Size: 206 KB
- Stars: 1
- Watchers: 1
- Forks: 2
- Open Issues: 1
-
Metadata Files:
- Readme: README.adoc
- License: LICENSE
Awesome Lists containing this project
README
// suppress inspection "GrazieInspection" for whole file
= Using Resilience4j with Vert.x
:page-permalink: /
:page-github: vertx-howtos/resilience4j-howtoifdef::env-github[]
image:https://github.com/vertx-howtos/resilience4j-howto/workflows/Publish%20the%20how-to/badge.svg["Build Status", link="https://github.com/vertx-howtos/resilience4j-howto/actions?query=workflow%3A%22Publish+the+how-to%22"]
endif::env-github[]This document will show you how to use Resilience4j in Vert.x applications.
link:https://resilience4j.readme.io/[Resilience4j] is a popular library that implements common fault tolerance strategies:
* bulkhead (concurrency limiter)
* circuit breaker
* rate limiter
* retry
* time limiter (timeout)In this how-to, we only demonstrate the usage of a circuit breaker, but the repository of this how-to contains Vert.x adapters for all strategies mentioned above.
WARNING: Resilience4j 2.0, which we'll use here, requires Java 17.
== What you will build
You will use a circuit breaker with an HTTP client to prevent executing requests against a server that keeps returning errors.
This serves two main purposes:* avoid generating more load on a server that may be overloaded,
* failing fast when failure is very likely to occur anyway.The application consists of a few classes:
. the `CircuitBreakerVerticle` class
. the `VertxCircuitBreaker` adapter, which is included in the repository of this how-to== What you need
* A text editor or IDE
* Java 17 or higher
* Maven or Gradle== Create a project
The code of this project contains Maven and Gradle build files that are functionally equivalent.
=== Using Maven
First, your `pom.xml` file should declare version properties:
ifdef::env-github[]
link:pom.xml[Maven POM file]
endif::env-github[]
ifndef::env-github[]
[source,xml,indent=0]
.Maven `pom.xml`: version properties
----
include::pom.xml[tag=versions]
----
endif::env-github[]Next, import the Resilience4j and Vert.x BOMs to manage dependency versions:
ifdef::env-github[]
link:pom.xml[Maven POM file]
endif::env-github[]
ifndef::env-github[]
[source,xml,indent=0]
.Maven `pom.xml`: BOM imports
----
include::pom.xml[tag=bom]
----
endif::env-github[]Then, add a dependency on the Resilience4j circuit breaker library:
ifdef::env-github[]
link:pom.xml[Maven POM file]
endif::env-github[]
ifndef::env-github[]
[source,xml,indent=0]
.Maven `pom.xml`: Resilience4j dependency
----
include::pom.xml[tag=dependency-resilience4j]
----
endif::env-github[]Finally, add dependencies on the Vert.x Web and Vert.x Web Client libraries:
ifdef::env-github[]
link:pom.xml[Maven POM file]
endif::env-github[]
ifndef::env-github[]
[source,xml,indent=0]
.Maven `pom.xml`: Vert.x dependencies
----
include::pom.xml[tag=dependency-vertx]
----
endif::env-github[]=== Using Gradle
The `dependencies` block in your `build.gradle.kts` file (assuming you use Gradle with the Kotlin DSL) should first import the Resilience4j and Vert.x BOMs to manage dependency versions:
ifdef::env-github[]
link:build.gradle.kts[Gradle build file]
endif::env-github[]
ifndef::env-github[]
[source,kotlin,indent=0]
.Gradle `build.gradle.kts`: BOM imports
----
include::build.gradle.kts[tag=bom]
----
endif::env-github[]Then, add a dependency on the Resilience4j circuit breaker library:
ifdef::env-github[]
link:build.gradle.kts[Gradle build file]
endif::env-github[]
ifndef::env-github[]
[source,kotlin,indent=0]
.Gradle `build.gradle.kts`: Resilience4j dependency
----
include::build.gradle.kts[tag=dependency-resilience4j]
----
endif::env-github[]Finally, add dependencies on the Vert.x Web and Vert.x Web Client libraries:
ifdef::env-github[]
link:build.gradle.kts[Gradle build file]
endif::env-github[]
ifndef::env-github[]
[source,kotlin,indent=0]
.Gradle `build.gradle.kts`: Vert.x dependencies
----
include::build.gradle.kts[tag=dependency-vertx]
----
endif::env-github[]== Using circuit breaker to guard Vert.x Web Client requests
First, let's create the main `CircuitBreakerVerticle` class:
ifdef::env-github[]
link:src/main/java/io/vertx/howtos/resilience4j/CircuitBreakerVerticle.java[The `CircuitBreakerVerticle` class]
endif::env-github[]
ifndef::env-github[]
[source,java,indent=0]
.The `CircuitBreakerVerticle` class
----
include::src/main/java/io/vertx/howtos/resilience4j/CircuitBreakerVerticle.java[tag=class]
----
endif::env-github[]This class will use the `VertxCircuitBreaker` class, which is provided in the repository of this how-to.
=== Creating the circuit breaker
In the `start` method of the verticle, let's create a single circuit breaker instance that will be shared among all requests.
For demonstration purposes, we will configure the circuit breaker to start calculating the failure rate after mere 5 requests:ifdef::env-github[]
link:src/main/java/io/vertx/howtos/resilience4j/CircuitBreakerVerticle.java[The `CircuitBreakerVerticle` class]
endif::env-github[]
ifndef::env-github[]
[source,java,indent=0]
.Create the circuit breaker
----
include::src/main/java/io/vertx/howtos/resilience4j/CircuitBreakerVerticle.java[tag=circuit-breaker]
----
endif::env-github[]TIP: The default settings make a lot more sense for a real-world application than our demonstration configuration.
=== Creating a server
Next, we'll use Vert.x Web to expose a simple endpoint.
The sole purpose of that endpoint will be to perform an HTTP request and guard it with the circuit breaker:ifdef::env-github[]
link:src/main/java/io/vertx/howtos/resilience4j/CircuitBreakerVerticle.java[The `CircuitBreakerVerticle` class]
endif::env-github[]
ifndef::env-github[]
[source,java,indent=0]
.Create the endpoint
----
include::src/main/java/io/vertx/howtos/resilience4j/CircuitBreakerVerticle.java[tag=router]
----
endif::env-github[]This deserves some explanation.
The endpoint on `/` uses the `VertxCircuitBreaker` adapter that glues together the Resilience4j API and Vert.x ``Future``s.
The adapter expects a `Supplier` as an action to be guarded.The `Future` here comes from the Vert.x Web Client `get(8080, "localhost", "/does-not-exist")` call.
As you can imagine, the request we make here will never succeed.
Therefore, the circuit breaker will kick in after 5 requests (as configured above) and will prevent further calls to the guarded action.
Instead, the `Future` returned by `executeFuture` will fail instantly with the `CallNotPermittedException` exception.=== Starting the server
Finally, we'll start the server:
ifdef::env-github[]
link:src/main/java/io/vertx/howtos/resilience4j/CircuitBreakerVerticle.java[The `CircuitBreakerVerticle` class]
endif::env-github[]
ifndef::env-github[]
[source,java,indent=0]
.Start the server
----
include::src/main/java/io/vertx/howtos/resilience4j/CircuitBreakerVerticle.java[tag=server]
----
endif::env-github[]The entire `start` method of the verticle looks like this:
ifdef::env-github[]
link:src/main/java/io/vertx/howtos/resilience4j/CircuitBreakerVerticle.java[The `CircuitBreakerVerticle` class]
endif::env-github[]
ifndef::env-github[]
[source,java,indent=0]
.The `start` method of the verticle
----
include::src/main/java/io/vertx/howtos/resilience4j/CircuitBreakerVerticle.java[tag=start]
----
endif::env-github[]== Running the application
The `CircuitBreakerVerticle` also needs a `main` method:
ifdef::env-github[]
link:src/main/java/io/vertx/howtos/resilience4j/CircuitBreakerVerticle.java[The `CircuitBreakerVerticle` class]
endif::env-github[]
ifndef::env-github[]
[source,java,indent=0]
.The `main` method
----
include::src/main/java/io/vertx/howtos/resilience4j/CircuitBreakerVerticle.java[tag=main]
----
endif::env-github[]Then you can run the application:
* straight from your IDE, or
* with Maven: `mvn clean compile exec:java`, or
* with Gradle: `./gradlew run` (Linux, macOS) or `gradlew run` (Windows).The following examples use the https://httpie.org/[HTTPie] command line HTTP client.
Please refer to the https://httpie.org/doc#installation[installation] documentation if you don't have it installed on your system yet.=== First 5 requests
For the first 5 requests, the circuit breaker does not calculate the failure rate and will allow all actions to proceed.
As expected, they will all fail:[source,shell]
----
http localhost:8080
http localhost:8080
http localhost:8080
http localhost:8080
http localhost:8080
----You should see the following output 5 times:
[source,text]
----
Failed with: io.vertx.core.impl.NoStackTraceThrowable: Response status code 404 is not between 200 and 300
----=== Next, the circuit breaker kicks in
[source,shell]
----
http localhost:8080
----The 6th request will fail with a different message:
[source,text]
----
Failed with: io.github.resilience4j.circuitbreaker.CallNotPermittedException: CircuitBreaker 'my-circuit-breaker' is OPEN and does not permit further calls
----We see that the circuit breaker prevented the execution of the request against the server.
== Summary
This document covered:
. creating an instance of the Resilience4j circuit breaker,
. using the circuit breaker to guard an action whose result is a Vert.x `Future`.== See also
* link:https://resilience4j.readme.io/[The Resilience4j documentation]