api-breaker
Breaks the circuit to an unhealthy upstream and returns a fixed response.
api-breakerPriority 1005What it does
api-breaker stops sending requests to a route's backend once it has failed several times in a row. A failure is an answer carrying a code listed under HTTP statuses in Unhealthy, and Failures of them open the breaker.
While the breaker is open, the gateway answers the client itself, as How G8 handles a request describes, with Break response code and Break response body. In the example, a backend that cannot be reached is answered 502 five times, and the sixth request gets 503 with the example's own message.
When to use it
- An orders API whose backend falls over under load: after five failures in a row, clients get a fast
503instead of waiting on it. - A backend that needs time to recover, which every client retrying at once would keep down.
- An answer during an outage that a client can show, with a body of your own and a header that marks it, for example
X-Breaker. - A dependency that answers
504after a long wait, where every waiting request holds a connection open.
Not for taking one failing backend instance out of rotation while the others serve — see Upstream (Upstreams are the backends that routes and services send traffic to) or answering with an error on purpose to test clients — see fault-injection (Injects delays or fixed responses for testing).
Guides
Pages that walk through a job with api-breaker, step by step.
- Stop calling a failing backendAnswer clients from the gateway for a while once a route's backend keeps failing, and give the backend time to recover.
Set it up
Stop sending requests to a failing service after five errors in a row
The count is kept per host and path, and two answers that pass close the breaker again.
Set Break response code to 503, fill Unhealthy as in the JSON below, fill Healthy as in the JSON below, set Longest time the breaker stays open to 120 seconds and set Break response body to The orders service is temporarily unavailable..
{
"break_response_code": 503,
"break_response_body": "The orders service is temporarily unavailable.",
"unhealthy": {
"failures": 5,
"http_statuses": [
500,
502,
503,
504
]
},
"healthy": {
"successes": 2
},
"max_breaker_sec": 120
}
What you will see
- While the backend refuses connections, the first request is answered
502by the gateway, which still tried the backend. - The second request is answered
502the same way. - The third request is answered
502the same way. - The fourth request is answered
502the same way. - The fifth request is answered
502the same way; five failures in a row reach the threshold of Failures. - The sixth request is answered
503withThe orders service is temporarily unavailable.by the gateway itself, without reaching for the backend.
Things to know
- Break response body — Once five failures are counted, the next request does not reach the backend and is answered
503with the bodyThe orders service is temporarily unavailable. - HTTP statuses — Only what the upstream answered counts: a connection it refuses counts as 502, and a status this gateway produced itself never opens the breaker.
- HTTP statuses — A backend that cannot be reached counts as well: five requests answered
502for want of a connection open the breaker. - HTTP statuses — A code below
500, for example200, is refused when you save. - Failures — The count is kept per host and request path, so a route matching a prefix counts each path on its own.
- HTTP statuses — A code of
500or above is refused when you save. - Longest time the breaker stays open — The breaker first opens for two seconds and doubles that with every further round of failures, up to this many seconds.
- Longest time the breaker stays open — A ceiling below three seconds is refused when you save.
- Break response headers — These headers are sent only when a break response body is set, even an empty one, and without a body only the code is sent.
- AdviceGive the break answer a body of your own, so that a client and your logs tell it apart from an error the backend sent.
Settings
The fields as the console shows them, section by section.
break_response_codeintegerRequiredThe client is answered with this code while the breaker is open, and the upstream is not asked at all.
unhealthyobjectdefault {"failures":3,"http_statuses":[500]}unhealthy.failuresintegerdefault 3How many failures open the breaker, and each further round of this many opens it again for longer. The count is kept per host and request path, so a route matching a prefix counts each path on its own.
unhealthy.http_statusesarray of integersdefault [500]An answer carrying one of these counts as a failure.
healthyobjectdefault {"http_statuses":[200],"successes":3}healthy.http_statusesarray of integersdefault [200]An answer carrying one of these counts as a success once any failure has been counted.
healthy.successesintegerdefault 3How many successes in a row clear the failure count, so the next opening starts again at the shortest time. An answer in neither list leaves the count where it stands.
max_breaker_secintegerdefault 300break_response_bodystringSent as the whole body of that answer, exactly as it is written here.
break_response_headersarray of objectsbreak_response_headers[].keystringRequiredThe name of a header added to the break answer.
break_response_headers[].valuestringRequiredRead as a request variable where it begins with a dollar sign, so $host sends the host the refused request asked for.