circuitbreaker-lambda
is a basic Node module for using the circuit breaker pattern in AWS Lambda (https://aws.amazon.com/lambda) and general async functions. It relies on a pass/fail assumption. Thresholds and timeout values are configurable and there is support for using a fallback function for graceful degradation. State and counters for the circuit breaker is stored in an Amazon DynamoDB table.
- Install
circuitbreaker-lambda
module using NPM.
npm install circuitbreaker-lambda
- Import the
circuitbreaker-lambda
module in your Lambda function code.
const CircuitBreaker = require('circuitbreaker-lambda')
- Add options for the circuit breaker. This is optional and if all or single options are missing the circuit breaker will revert to defaults.
const options = {
fallback: fallbackFunction,
failureThreshold: 5,
successThreshold: 2,
timeout: 10000
}
- Instantiate the circuit breaker with the function and optional options.
const circuitBreaker = new CircuitBreaker(unreliableFunction, options)
- Add the fire function for the circuit breaker.
await circuitBreaker.fire()
- Create an Amazon DynamoDB table with a single attribute primary key. The primary key should be a String with a value of id.
aws dynamodb create-table \
--table-name circuitbreakerLambdaTable \
--attribute-definitions AttributeName=id,AttributeType=S \
--key-schema AttributeName=id,KeyType=HASH \
--billing-mode PAY_PER_REQUEST
- Give the Lambda function GetItem and UpdateItem permissions to the Lambda table.
{
"Action": [
"dynamodb:GetItem",
"dynamodb:UpdateItem"
],
"Resource": "arn:aws:dynamodb:eu-west-1:*:table/circuitbreakerLambdaTable",
"Effect": "Allow"
}
- Add an environment variable to your Lambda function with the key CIRCUITBREAKER_TABLE and the value set to the name of your table in Amazon DynamoDB.
- Try it out!
These are the different states for circuitbreaker-lambda
.
CLOSED
: Everything is working normally and all calls pass through to the circuit breakerOPEN
: Requests fail for a set amount of time. Fallback is used if configured.HALF
: Requests are let through to test the stability of the call. Fallback is used if configured.
These are the ways circuitbreaker-lambda
transitions between states.
CLOSED
toOPEN
: WhenfailureCount
greater than or equal tofailureThreshold
.OPEN
toHALF
: WhenDate.now()
greater than or equal tonextAttempt
.HALF
toOPEN
: When failure occurs inHALF
state.HALF
toCLOSED
: WhensuccessCount
greater than or equal tosuccessThreshold
.
You can optionally add options and control the behavior of circuitbreaker-lambda
.
const options = {
fallback: fallbackFunction,
failureThreshold: 5,
successThreshold: 2,
timeout: 10000
}
fallback:
Add this option if you wish to use a fallback function in case of failure. Use the name of your function.failureThreshold:
The number of failed attempts before the circuit breaker changes state toOPEN
.successThreshold
The number of successful attempts while the state isHALF
before the circuit breaker changes state toCLOSED
.timeout
The timeout after the circuit breaker changed state toOPEN
before it will attempt the regular function call again.
These are the default values used if options aren't defined.
const defaults = {
fallback: null,
failureThreshold: 5,
successThreshold: 2,
timeout: 10000
}
In the subfolder example
is a simple Serverless Framework template and an AWS SAM template which will install an example application with a Lambda function and a DynamoDB table. The example Lambda function has circuitbreaker-lambda
installed, an example unreliableFunction which fails about 60 percent of the time (Math.random() < 0.6
), and an example fallbackFunction.
npm install
sls deploy
npm install
sam build
sam deploy --guided
Inspired by Michael Nygard's book Release it! (https://www.amazon.com/gp/product/0978739213), Martin Fowler's article on the circuit breaker (https://martinfowler.com/bliki/CircuitBreaker.html), and Mark Michon's post on building a Node.js circuit breaker (https://blog.bearer.sh/build-a-circuit-breaker-in-node-js/).
- Initial release