Moving common spring-cloud-circuitbreaker code to commons
This commit is contained in:
82
docs/src/main/asciidoc/spring-cloud-circuitbreaker.adoc
Executable file
82
docs/src/main/asciidoc/spring-cloud-circuitbreaker.adoc
Executable file
@@ -0,0 +1,82 @@
|
||||
== Introduction
|
||||
|
||||
Spring Cloud Circuit breaker provides an abstraction across different circuit breaker implementations.
|
||||
It provides a consistent API to use in your applications allowing you the developer to choose the circuit breaker implementation that best fits your needs for your app.
|
||||
|
||||
=== Supported Implementations
|
||||
|
||||
* https://github.com/Netflix/Hystrix[Netfix Hystrix]
|
||||
* https://github.com/resilience4j/resilience4j[Resilience4J]
|
||||
* https://github.com/alibaba/Sentinel[Sentinel]
|
||||
* https://github.com/spring-projects/spring-retry[Spring Retry]
|
||||
|
||||
== Core Concepts
|
||||
|
||||
To create a circuit breaker in your code you can use the `CircuitBreakerFactory` API. When you include a Spring Cloud Circuit Breaker starter on your classpath a bean implementing this API will automatically be created for you.
|
||||
A very simple example of using this API is given below
|
||||
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
@Service
|
||||
public static class DemoControllerService {
|
||||
private RestTemplate rest;
|
||||
private CircuitBreakerFactory cbFactory;
|
||||
|
||||
public DemoControllerService(RestTemplate rest, CircuitBreakerFactory cbFactory) {
|
||||
this.rest = rest;
|
||||
this.cbFactory = cbFactory;
|
||||
}
|
||||
|
||||
public String slow() {
|
||||
return cbFactory.create("slow").run(() -> rest.getForObject("/slow", String.class), throwable -> "fallback");
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
The `CircuitBreakerFactory.create` API will create an instance of a class called `CircuitBreaker`.
|
||||
The `run` method takes a `Supplier` and a `Function`.
|
||||
The `Supplier` is the code that you are going to wrap in a circuit breaker.
|
||||
The `Function` is the fallback that will be executed if the circuit breaker is tripped.
|
||||
The function will be passed the `Throwable` that caused the fallback to be triggered.
|
||||
You can optionally exclude the fallback if you do not want to provide one.
|
||||
|
||||
=== Circuit Breakers In Reactive Code
|
||||
|
||||
If Project Reactor is on the class path then you can also use `ReactiveCircuitBreakerFactory` for your reactive code.
|
||||
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
@Service
|
||||
public static class DemoControllerService {
|
||||
private ReactiveCircuitBreakerFactory cbFactory;
|
||||
private WebClient webClient;
|
||||
|
||||
|
||||
public DemoControllerService(WebClient webClient, ReactiveCircuitBreakerFactory cbFactory) {
|
||||
this.webClient = webClient;
|
||||
this.cbFactory = cbFactory;
|
||||
}
|
||||
|
||||
public Mono<String> slow() {
|
||||
return webClient.get().uri("/slow").retrieve().bodyToMono(String.class).transform(
|
||||
it -> cbFactory.create("slow").run(it, throwable -> return Mono.just("fallback")));
|
||||
}
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
The `ReactiveCircuitBreakerFactory.create` API will create an instance of a class called `ReactiveCircuitBreaker`.
|
||||
The `run` method takes with a `Mono` or `Flux` and wraps it in a circuit breaker.
|
||||
You can optionally profile a fallback `Function` which will be called if the circuit breaker is tripped and will be passed the `Throwable`
|
||||
that caused the failure.
|
||||
|
||||
== Configuration
|
||||
|
||||
You can configure your circuit breakers using by creating beans of type `Customizer`.
|
||||
The `Customizer` interface has a single method called `customize` that takes in the `Object` to customize.
|
||||
|
||||
// TODO link to implementation docs
|
||||
@@ -767,4 +767,8 @@ If you want to learn more about the Spring Cloud Release train compatibility, yo
|
||||
In order to disable this feature, set `spring.cloud.compatibility-verifier.enabled` to `false`.
|
||||
If you want to override the compatible Spring Boot versions, just set the
|
||||
`spring.cloud.compatibility-verifier.compatible-boot-versions` property with a comma separated list
|
||||
of compatible Spring Boot versions.
|
||||
of compatible Spring Boot versions.
|
||||
|
||||
== Spring Cloud Circuit Breaker
|
||||
|
||||
include::spring-cloud-circuitbreaker.adoc[]
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.client.circuitbreaker;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Base class for factories which produce circuit breakers.
|
||||
*
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
public abstract class AbstractCircuitBreakerFactory<CONF, CONFB extends ConfigBuilder<CONF>> {
|
||||
|
||||
private final ConcurrentHashMap<String, CONF> configurations = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Adds configurations for circuit breakers.
|
||||
* @param ids The id of the circuit breaker
|
||||
* @param consumer A configuration builder consumer, allows consumers to customize the
|
||||
* builder before the configuration is built
|
||||
*/
|
||||
public void configure(Consumer<CONFB> consumer, String... ids) {
|
||||
for (String id : ids) {
|
||||
CONFB builder = configBuilder(id);
|
||||
consumer.accept(builder);
|
||||
CONF conf = builder.build();
|
||||
getConfigurations().put(id, conf);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the configurations for the circuit breakers.
|
||||
* @return The configurations
|
||||
*/
|
||||
protected ConcurrentHashMap<String, CONF> getConfigurations() {
|
||||
return configurations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a configuration builder for the given id.
|
||||
* @param id The id of the circuit breaker
|
||||
* @return The configuration builder
|
||||
*/
|
||||
protected abstract CONFB configBuilder(String id);
|
||||
|
||||
/**
|
||||
* Sets the default configuration for circuit breakers.
|
||||
* @param defaultConfiguration A function that returns the default configuration
|
||||
*/
|
||||
public abstract void configureDefault(Function<String, CONF> defaultConfiguration);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.client.circuitbreaker;
|
||||
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Spring Cloud circuit breaker.
|
||||
*
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
public interface CircuitBreaker {
|
||||
|
||||
default <T> T run(Supplier<T> toRun) {
|
||||
return run(toRun, throwable -> {
|
||||
throw new NoFallbackAvailableException("No fallback available.", throwable);
|
||||
});
|
||||
};
|
||||
|
||||
<T> T run(Supplier<T> toRun, Function<Throwable, T> fallback);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.client.circuitbreaker;
|
||||
|
||||
/**
|
||||
* Creates circuit breakers based on the underlying implementation.
|
||||
*
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
public abstract class CircuitBreakerFactory<CONF, CONFB extends ConfigBuilder<CONF>>
|
||||
extends AbstractCircuitBreakerFactory<CONF, CONFB> {
|
||||
|
||||
public abstract CircuitBreaker create(String id);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.client.circuitbreaker;
|
||||
|
||||
/**
|
||||
* A builder for circuit breaker configurations.
|
||||
*
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
public interface ConfigBuilder<CONF> {
|
||||
|
||||
CONF build();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.client.circuitbreaker;
|
||||
|
||||
/**
|
||||
* Customizes the parameterized class.
|
||||
*
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
public interface Customizer<TOCUSTOMIZE> {
|
||||
|
||||
void customize(TOCUSTOMIZE tocustomize);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.client.circuitbreaker;
|
||||
|
||||
/**
|
||||
* A runtime exception that tells no fallback is available for the circuit breaker.
|
||||
*
|
||||
* @author Toshiaki Maki
|
||||
*/
|
||||
public class NoFallbackAvailableException extends RuntimeException {
|
||||
|
||||
public NoFallbackAvailableException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.client.circuitbreaker;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* Spring Cloud reactive circuit breaker API.
|
||||
*
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
public interface ReactiveCircuitBreaker {
|
||||
|
||||
default <T> Mono<T> run(Mono<T> toRun) {
|
||||
return run(toRun, throwable -> {
|
||||
throw new NoFallbackAvailableException("No fallback available.", throwable);
|
||||
});
|
||||
}
|
||||
|
||||
<T> Mono<T> run(Mono<T> toRun, Function<Throwable, Mono<T>> fallback);
|
||||
|
||||
default <T> Flux<T> run(Flux<T> toRun) {
|
||||
return run(toRun, throwable -> {
|
||||
throw new NoFallbackAvailableException("No fallback available.", throwable);
|
||||
});
|
||||
}
|
||||
|
||||
<T> Flux<T> run(Flux<T> toRun, Function<Throwable, Flux<T>> fallback);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2013-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.client.circuitbreaker;
|
||||
|
||||
/**
|
||||
* Creates reactive circuit breakers.
|
||||
*
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
public abstract class ReactiveCircuitBreakerFactory<CONF, CONFB extends ConfigBuilder<CONF>>
|
||||
extends AbstractCircuitBreakerFactory<CONF, CONFB> {
|
||||
|
||||
public abstract ReactiveCircuitBreaker create(String id);
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user