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-lambdamodule using NPM.
npm install circuitbreaker-lambda- Import the
circuitbreaker-lambdamodule 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.
CLOSEDtoOPEN: WhenfailureCountgreater than or equal tofailureThreshold.OPENtoHALF: WhenDate.now()greater than or equal tonextAttempt.HALFtoOPEN: When failure occurs inHALFstate.HALFtoCLOSED: WhensuccessCountgreater 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.successThresholdThe number of successful attempts while the state isHALFbefore the circuit breaker changes state toCLOSED.timeoutThe timeout after the circuit breaker changed state toOPENbefore 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 deploynpm install
sam build
sam deploy --guidedInspired 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
