diff --git a/README.md b/README.md
index e2774f065..7ae6f7c03 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,9 @@
[](https://travis-ci.org/spring-petclinic/spring-petclinic-microservices/) [](https://opensource.org/licenses/Apache-2.0)
-This microservices branch was initially derived from [AngularJS version](https://github.com/spring-petclinic/spring-petclinic-angular1) to demonstrate how to split sample Spring application into [microservices](http://www.martinfowler.com/articles/microservices.html). To achieve that goal we used [Spring Cloud Netflix](https://github.com/spring-cloud/spring-cloud-netflix) technology stack.
+This microservices branch was initially derived from [AngularJS version](https://github.com/spring-petclinic/spring-petclinic-angular1) to demonstrate how to split sample Spring application into [microservices](http://www.martinfowler.com/articles/microservices.html).
+To achieve that goal we use Spring Cloud Gateway, Spring Cloud Circuit Breaker, Spring Cloud Config, Spring Cloud Sleuth, Resilience4j, Micrometer
+and the Eureka Service Discovery from the [Spring Cloud Netflix](https://github.com/spring-cloud/spring-cloud-netflix) technology stack.
## Starting services locally without Docker
@@ -17,10 +19,6 @@ If everything goes well, you can access the following services at given location
* Admin Server (Spring Boot Admin) - http://localhost:9090
* Grafana Dashboards - http://localhost:3000
* Prometheus - http://localhost:9091
-* Hystrix Dashboard for Circuit Breaker pattern - http://localhost:7979 - On the home page is a form where you can enter
-the URL for an event stream to monitor, for example the `api-gateway` service running locally: `http://localhost:8080/actuator/hystrix.stream`
-or running into docker: `http://api-gateway:8080/actuator/hystrix.stream`
-
You can tell Config Server to use your local Git repository by using `native` Spring profile and setting
`GIT_REPO` environment variable, for example:
@@ -131,7 +129,7 @@ All those three REST controllers `OwnerResource`, `PetResource` and `VisitResour
| Service Discovery | [Eureka server](spring-petclinic-discovery-server) and [Service discovery client](spring-petclinic-vets-service/src/main/java/org/springframework/samples/petclinic/vets/VetsServiceApplication.java) |
| API Gateway | [Spring Cloud Gateway starter](spring-petclinic-api-gateway/pom.xml) and [Routing configuration](/spring-petclinic-api-gateway/src/main/resources/application.yml) |
| Docker Compose | [Spring Boot with Docker guide](https://spring.io/guides/gs/spring-boot-docker/) and [docker-compose file](docker-compose.yml) |
-| Circuit Breaker | [Hystrix fallback method](spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/application/VisitsServiceClient.java) |
+| Circuit Breaker | [Resilience4j fallback method](spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/boundary/web/ApiGatewayController.java) |
| Grafana / Prometheus Monitoring | [Micrometer implementation](https://micrometer.io/), [Spring Boot Actuator Production Ready Metrics] |
Front-end module | Files |
diff --git a/docker-compose.yml b/docker-compose.yml
index da6b7b337..93c0a42d3 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -82,17 +82,6 @@ services:
ports:
- 9090:9090
- hystrix-dashboard:
- image: springcommunity/spring-petclinic-hystrix-dashboard
- container_name: hystrix-dashboard
- mem_limit: 512M
- depends_on:
- - config-server
- - discovery-server
- entrypoint: ["./dockerize","-wait=tcp://discovery-server:8761","-timeout=60s","--","java", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseCGroupMemoryLimitForHeap", "-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
- ports:
- - 7979:7979
-
## Grafana / Prometheus
grafana-server:
diff --git a/pom.xml b/pom.xml
index cd85814de..33d6a39e3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,7 +23,6 @@
spring-petclinic-config-server
spring-petclinic-discovery-server
spring-petclinic-api-gateway
- spring-petclinic-hystrix-dashboard
diff --git a/spring-petclinic-api-gateway/pom.xml b/spring-petclinic-api-gateway/pom.xml
index 7b66f6c21..98fc2fbb6 100644
--- a/spring-petclinic-api-gateway/pom.xml
+++ b/spring-petclinic-api-gateway/pom.xml
@@ -53,6 +53,10 @@
org.springframework.cloud
spring-cloud-sleuth-zipkin
+
+ org.springframework.cloud
+ spring-cloud-starter-circuitbreaker-reactor-resilience4j
+
org.springframework.cloud
spring-cloud-starter-config
@@ -73,6 +77,10 @@
com.netflix.ribbon
ribbon-eureka
+
+ org.springframework.cloud
+ spring-cloud-netflix-hystrix
+
@@ -83,16 +91,6 @@
org.springframework.cloud
spring-cloud-starter-gateway
-
- org.springframework.cloud
- spring-cloud-starter-netflix-hystrix
-
-
- org.springframework.cloud
- spring-cloud-netflix-ribbon
-
-
-
@@ -107,6 +105,10 @@
io.micrometer
micrometer-registry-prometheus
+
+ io.github.resilience4j
+ resilience4j-micrometer
+
diff --git a/spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/ApiGatewayApplication.java b/spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/ApiGatewayApplication.java
index 1add5f1d8..fd13cc08d 100644
--- a/spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/ApiGatewayApplication.java
+++ b/spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/ApiGatewayApplication.java
@@ -15,10 +15,14 @@
*/
package org.springframework.samples.petclinic.api;
+import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig;
+import io.github.resilience4j.timelimiter.TimeLimiterConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
+import org.springframework.cloud.circuitbreaker.resilience4j.ReactiveResilience4JCircuitBreakerFactory;
+import org.springframework.cloud.circuitbreaker.resilience4j.Resilience4JConfigBuilder;
+import org.springframework.cloud.client.circuitbreaker.Customizer;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
@@ -32,12 +36,13 @@
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;
+import java.time.Duration;
+
/**
* @author Maciej Szarlinski
*/
@EnableDiscoveryClient
-@EnableCircuitBreaker
@SpringBootApplication
public class ApiGatewayApplication {
@@ -71,4 +76,15 @@ RouterFunction> routerFunction() {
request -> ServerResponse.ok().contentType(MediaType.TEXT_HTML).bodyValue(indexHtml));
return router;
}
+
+ /**
+ * Default Resilience4j circuit breaker configuration
+ */
+ @Bean
+ public Customizer defaultCustomizer() {
+ return factory -> factory.configureDefault(id -> new Resilience4JConfigBuilder(id)
+ .circuitBreakerConfig(CircuitBreakerConfig.ofDefaults())
+ .timeLimiterConfig(TimeLimiterConfig.custom().timeoutDuration(Duration.ofSeconds(4)).build())
+ .build());
+ }
}
diff --git a/spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/application/VisitsServiceClient.java b/spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/application/VisitsServiceClient.java
index 8f9c392a9..ffb3d848a 100644
--- a/spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/application/VisitsServiceClient.java
+++ b/spring-petclinic-api-gateway/src/main/java/org/springframework/samples/petclinic/api/application/VisitsServiceClient.java
@@ -16,15 +16,12 @@
package org.springframework.samples.petclinic.api.application;
import lombok.RequiredArgsConstructor;
-import org.springframework.samples.petclinic.api.dto.VisitDetails;
import org.springframework.samples.petclinic.api.dto.Visits;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
-import java.util.Collections;
import java.util.List;
-import java.util.Map;
import static java.util.stream.Collectors.joining;
@@ -40,7 +37,6 @@ public class VisitsServiceClient {
private final WebClient.Builder webClientBuilder;
- // FIXME HYSTRIX @HystrixCommand(fallbackMethod = "emptyVisitsForPets")
public Mono getVisitsForPets(final List petIds) {
return webClientBuilder.build()
.get()
@@ -53,10 +49,6 @@ private String joinIds(List petIds) {
return petIds.stream().map(Object::toString).collect(joining(","));
}
- private Mono