|
| 1 | +<div class="anchored-md"> |
| 2 | +{{#assign "markdown"}} |
| 3 | +It's inevitable that your system will have failures whether they are caused by bugs, network partitions, load, etc. What is important is being able to recover and recovering quickly. There have been some great resiliency libraries released in Java over the past few years. We found Netflix's [Hystrix](https://github.com/Netflix/Hystrix) to have a higher learning curve and a bit more complicated to use. We opted for [Failsafe](https://github.com/jhalterman/failsafe) which has more of an opt in model to only use what you want. We will outline how to circuit break your web server to help fail fast and recover quicker. |
| 4 | + |
| 5 | +## What is a Circuit Breaker? |
| 6 | +The Wikipedia definition of a [circuit breaker](https://en.wikipedia.org/wiki/Circuit_breaker). "A circuit breaker is an automatically operated electrical switch designed to protect an electrical circuit from damage caused by overcurrent, typically resulting from an overload or short circuit. Its basic function is to interrupt current flow after a fault is detected. Unlike a fuse, which operates once and then must be replaced, a circuit breaker can be reset (either manually or automatically) to resume normal operation." In software we can think of this as a fail fast mechanism that will stop a code path once it notices a certain failure rate. This will hopefully give the system time to recover or at least allow other code paths to function while this one is down. |
| 7 | + |
| 8 | +### Example Failsafe Circuit Breaker |
| 9 | +{{> templates/src/widgets/code/code-snippet file=example section=example.sections.breaker}} |
| 10 | + |
| 11 | +## Circuit Breaker HttpHandler |
| 12 | +Let's utilize a `CircuitBreaker` to create a reusable `HttpHandler` that can circuit break based on a passed in `CircuitBreaker`. This could be useful if some resource pool is constrained and we want to help relieve some back-pressure by not sending any new requests. Another use case is potentially we have some bug such as forgetting to paginate a SQL query and just one specific endpoint is hanging non stop. Utilizing a `CircuitBreaker` we can automatically start shutting off individual endpoints or maybe an entire service as a whole using [middleware](/posts/logging-gzip-blocking-exception-handling-metrics-middleware-chaining-in-undertow). Keep in mind that techniques such as this can hurt you just as much as they help you if they are not configured well. |
| 13 | + |
| 14 | +{{> templates/src/widgets/code/code-snippet file=handler section=handler.sections.handler}} |
| 15 | + |
| 16 | +## Example Handlers |
| 17 | +Here we have a `HttpHandler` that we can easily mimic some errors in as well as a `HttpHander` that returns a 500 - server error. |
| 18 | + |
| 19 | +{{> templates/src/widgets/code/code-snippet file=example section=example.sections.handlers}} |
| 20 | + |
| 21 | +## Making some Requests |
| 22 | +Here is a quick little method to use [OkHttp](/posts/okhttp-example-rest-client) to send a HTTP request to our example server. |
| 23 | + |
| 24 | +{{> templates/src/widgets/code/code-snippet file=example section=example.sections.request}} |
| 25 | + |
| 26 | +## Example Server |
| 27 | +Finally we can start up a server and send some requests at it with a `ScheduledExecutorService`. |
| 28 | + |
| 29 | +{{> templates/src/widgets/code/code-snippet file=example section=example.sections.main}} |
| 30 | + |
| 31 | +### Output |
| 32 | +<pre class="line-numbers"><code class="language-bash">2018-02-05 23:43:16.168 [main] INFO c.s.common.undertow.SimpleServer - ListenerInfo{protcol='http', address=/0:0:0:0:0:0:0:0:8080, sslContext=null} |
| 33 | +2018-02-05 23:43:16.542 [main] INFO c.s.e.failsafe.FailsafeWebserver - warmup Circuit is open everything is functioning properly. |
| 34 | +2018-02-05 23:43:16.549 [main] INFO c.s.e.failsafe.FailsafeWebserver - warmup Circuit is open everything is functioning properly. |
| 35 | +2018-02-05 23:43:16.553 [main] INFO c.s.e.failsafe.FailsafeWebserver - warmup Circuit is open everything is functioning properly. |
| 36 | +2018-02-05 23:43:16.554 [main] INFO c.s.e.failsafe.FailsafeWebserver - warmup Circuit is open everything is functioning properly. |
| 37 | +2018-02-05 23:43:16.556 [main] INFO c.s.e.failsafe.FailsafeWebserver - warmup Circuit is open everything is functioning properly. |
| 38 | +2018-02-05 23:43:16.557 [main] INFO c.s.e.failsafe.FailsafeWebserver - warmup Circuit is open everything is functioning properly. |
| 39 | +2018-02-05 23:43:16.559 [main] INFO c.s.e.failsafe.FailsafeWebserver - warmup Circuit is open everything is functioning properly. |
| 40 | +2018-02-05 23:43:16.561 [main] INFO c.s.e.failsafe.FailsafeWebserver - warmup Circuit is open everything is functioning properly. |
| 41 | +2018-02-05 23:43:16.562 [main] INFO c.s.e.failsafe.FailsafeWebserver - warmup Circuit is open everything is functioning properly. |
| 42 | +2018-02-05 23:43:16.564 [main] INFO c.s.e.failsafe.FailsafeWebserver - warmup Circuit is open everything is functioning properly. |
| 43 | +2018-02-05 23:43:16.568 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - ping Circuit is open everything is functioning properly. |
| 44 | +2018-02-05 23:43:17.068 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - ping Circuit is open everything is functioning properly. |
| 45 | +2018-02-05 23:43:17.568 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - ping Circuit is open everything is functioning properly. |
| 46 | +2018-02-05 23:43:17.568 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - Start: Executing bad requests! |
| 47 | +2018-02-05 23:43:17.569 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - bad request Bad Request |
| 48 | +2018-02-05 23:43:17.570 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - bad request Bad Request |
| 49 | +2018-02-05 23:43:17.572 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - bad request Bad Request |
| 50 | +2018-02-05 23:43:17.574 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - bad request Bad Request |
| 51 | +2018-02-05 23:43:17.575 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - bad request Bad Request |
| 52 | +2018-02-05 23:43:17.576 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - bad request Bad Request |
| 53 | +2018-02-05 23:43:17.577 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - bad request Bad Request |
| 54 | +2018-02-05 23:43:17.578 [XNIO-1 I/O-2] INFO c.s.e.failsafe.FailsafeWebserver - Circuit Opened |
| 55 | +2018-02-05 23:43:17.580 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - bad request 500 - Internal Server Error |
| 56 | +2018-02-05 23:43:17.581 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - bad request 500 - Internal Server Error |
| 57 | +2018-02-05 23:43:17.583 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - bad request 500 - Internal Server Error |
| 58 | +2018-02-05 23:43:17.584 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - bad request 500 - Internal Server Error |
| 59 | +2018-02-05 23:43:17.585 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - bad request 500 - Internal Server Error |
| 60 | +2018-02-05 23:43:17.587 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - bad request 500 - Internal Server Error |
| 61 | +2018-02-05 23:43:17.588 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - bad request 500 - Internal Server Error |
| 62 | +2018-02-05 23:43:17.589 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - bad request 500 - Internal Server Error |
| 63 | +2018-02-05 23:43:17.589 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - End: Executing bad requests! |
| 64 | +2018-02-05 23:43:18.070 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - ping 500 - Internal Server Error |
| 65 | +2018-02-05 23:43:18.568 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - ping 500 - Internal Server Error |
| 66 | +2018-02-05 23:43:19.068 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - ping 500 - Internal Server Error |
| 67 | +2018-02-05 23:43:19.570 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - ping 500 - Internal Server Error |
| 68 | +2018-02-05 23:43:20.070 [XNIO-1 I/O-2] INFO c.s.e.failsafe.FailsafeWebserver - Circuit Half-Open |
| 69 | +2018-02-05 23:43:20.071 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - ping Circuit is open everything is functioning properly. |
| 70 | +2018-02-05 23:43:20.573 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - ping Circuit is open everything is functioning properly. |
| 71 | +2018-02-05 23:43:21.068 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - ping Circuit is open everything is functioning properly. |
| 72 | +2018-02-05 23:43:21.569 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - ping Circuit is open everything is functioning properly. |
| 73 | +2018-02-05 23:43:21.570 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - Start: Executing requests that throw exceptions! |
| 74 | +2018-02-05 23:43:21.571 [XNIO-1 I/O-2] INFO c.s.e.failsafe.FailsafeWebserver - Circuit Closed |
| 75 | +2018-02-05 23:43:21.572 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - exception request 500 - Internal Server Error |
| 76 | +2018-02-05 23:43:21.574 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - exception request 500 - Internal Server Error |
| 77 | +2018-02-05 23:43:21.575 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - exception request 500 - Internal Server Error |
| 78 | +2018-02-05 23:43:21.576 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - exception request 500 - Internal Server Error |
| 79 | +2018-02-05 23:43:21.578 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - exception request 500 - Internal Server Error |
| 80 | +2018-02-05 23:43:21.579 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - exception request 500 - Internal Server Error |
| 81 | +2018-02-05 23:43:21.581 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - exception request 500 - Internal Server Error |
| 82 | +2018-02-05 23:43:21.583 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - exception request 500 - Internal Server Error |
| 83 | +2018-02-05 23:43:21.584 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - exception request 500 - Internal Server Error |
| 84 | +2018-02-05 23:43:21.585 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - exception request 500 - Internal Server Error |
| 85 | +2018-02-05 23:43:21.586 [XNIO-1 I/O-2] INFO c.s.e.failsafe.FailsafeWebserver - Circuit Opened |
| 86 | +2018-02-05 23:43:21.587 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - exception request 500 - Internal Server Error |
| 87 | +2018-02-05 23:43:21.587 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - exception request 500 - Internal Server Error |
| 88 | +2018-02-05 23:43:21.589 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - exception request 500 - Internal Server Error |
| 89 | +2018-02-05 23:43:21.590 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - exception request 500 - Internal Server Error |
| 90 | +2018-02-05 23:43:21.591 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - exception request 500 - Internal Server Error |
| 91 | +2018-02-05 23:43:21.591 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - End: Executing requests that throw exceptions! |
| 92 | +2018-02-05 23:43:22.071 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - ping 500 - Internal Server Error |
| 93 | +2018-02-05 23:43:22.572 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - ping 500 - Internal Server Error |
| 94 | +2018-02-05 23:43:23.072 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - ping 500 - Internal Server Error |
| 95 | +2018-02-05 23:43:23.573 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - ping 500 - Internal Server Error |
| 96 | +2018-02-05 23:43:24.068 [XNIO-1 I/O-2] INFO c.s.e.failsafe.FailsafeWebserver - Circuit Half-Open |
| 97 | +2018-02-05 23:43:24.069 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - ping Circuit is open everything is functioning properly. |
| 98 | +2018-02-05 23:43:24.573 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - ping Circuit is open everything is functioning properly. |
| 99 | +2018-02-05 23:43:25.069 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - ping Circuit is open everything is functioning properly. |
| 100 | +2018-02-05 23:43:25.572 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - ping Circuit is open everything is functioning properly. |
| 101 | +2018-02-05 23:43:26.068 [XNIO-1 I/O-2] INFO c.s.e.failsafe.FailsafeWebserver - Circuit Closed |
| 102 | +2018-02-05 23:43:26.069 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - ping Circuit is open everything is functioning properly. |
| 103 | +2018-02-05 23:43:26.569 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - ping Circuit is open everything is functioning properly. |
| 104 | +2018-02-05 23:43:27.069 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - ping Circuit is open everything is functioning properly. |
| 105 | +2018-02-05 23:43:27.570 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - ping Circuit is open everything is functioning properly. |
| 106 | +2018-02-05 23:43:28.073 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - ping Circuit is open everything is functioning properly. |
| 107 | +2018-02-05 23:43:28.572 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - ping Circuit is open everything is functioning properly. |
| 108 | +2018-02-05 23:43:29.072 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - ping Circuit is open everything is functioning properly. |
| 109 | +2018-02-05 23:43:29.569 [pool-1-thread-1] INFO c.s.e.failsafe.FailsafeWebserver - ping Circuit is open everything is functioning properly.</code></pre> |
| 110 | + |
| 111 | +{{/assign}} |
| 112 | +{{md markdown}} |
| 113 | +</div> |
0 commit comments