A circuit breaker design pattern for dropwizard

Overview

Status

CircleCI Coverage Status Codacy Badge Download Javadoc License Dependency Status

Circuit Breaker Library

This library provides a simple implementation of a circuit breaker design pattern.

It uses dropwizard metrics to provide insights on the rate of failures and, with it, we can reliably assume a certain functionality is having issues. After a certain threshold is hit the circuit is opened and an exception is thrown, preventing from increasing the load on the failing code.

This library can be used as a stand-alone library or embedded into dropwizard, through the usage of annotations.

Project lombok was used to auto-generate the getter and setters, so you will need to have lombok plugin installed in your eclipse/intellij if you want to import the source code. The project also uses Java 8 features, such as Optional and lambda expressions, so it's not compatible with prior versions.

These are the supported versions of dropwizard:

Dropwizard Circuit Breaker
0.8.X 0.0.2
0.9.X 0.0.6
1.0.0 1.0.0
1.0.5 1.0.5
1.1.0 1.1.0
1.3.8 1.3.8
2.0.0 2.0.0

Stand-alone

To use this library as a stand-alone circuit breaker, you will need to build the object and pass a MetricRegistry. And it can be used to wrap code blocks, which can throw exceptions.

// We build the CircuitBreakerManager with a threshold of 0.5 failure per second and we'll
// be using a 1-minute average rate to determine if our circuit should be opened or not.
CircuitBreakerManager circuitBreaker = new CircuitBreakerManager(metricRegistry, 0.5, CircuitBreakerManager.RateType.ONE_MINUTE);
// When this exception below is thrown, the meter will be increased.
circuitBreaker.wrapCodeBlockWithCircuitBreaker("my.test.block", (meter) -> {
    // This is where you should put your code.

});

After several exceptions, and when the rate reaches the threshold, the method wrapCodeBlockWithCircuitBreaker() will thrown a CircuitBreakerOpenedException and won't run the code block anymore. Alternatively you can run it without throwing an exception, but you need to manually verify if the circuit is opened.

CircuitBreakerManager circuitBreaker = new CircuitBreakerManager(metricRegistry, 0.5, CircuitBreakerManager.RateType.ONE_MINUTE);

if (!circuitBreaker.isCircuitOpen("my.test.block")) {
    // This method will not throw an exception if our circuit is open.
    circuitBreaker.wrapCodeBlock("my.test.block", (meter) -> {
        // This is where you should put your code.

    });
}

With dropwizard

This library seamlessly integrates with dropwizard and provides the annotation @CircuitBreaker and it can be used to decorate the resource methods that will use the circuit breaker. When the API has reached a certain rate of exceptions it will automatically return 503 Service Unavailable until the rate drops below the threshold.

The usage of this design pattern can help alleviate the load when errors cascades from internal dependencies and surfaces into the outermost APIs. As the API starts returning 503 the clients will fail, either gracefully or not but that's outside of the scope of the back end, and the load will decrease on the internal dependencies that were causing the cascading failures.

This library also provides a configuration class (CircuitBreaker) that can be used in the application configuration class and a bundle class (CircuitBreakerBundle) to automatically register the circuit breaker with the application.

The annotation @CircuitBreaker should not be used in conjunction with @ExceptionMetered as they both will conflict when creating and registering the Meter. As they both are essentially measuring the same thing you won't need the @ExceptionMetered annotation.

Configuration

The configuration class can add reference to CircuitBreaker class, which holds the threshold and rate type:

public class MyAppConfiguration extends Configuration {
    private CircuitBreakerConfiguration circuitBreaker;
    
    public CircuitBreakerConfiguration getCircuitBreaker() {
        return this.circuitBreaker;
    }
}

Your configuration YML will look like this. The customThresholds allows having custom thresholds for specific circuit breakers.

circuitBreaker:
  threshold: 0.5
  rateType: ONE_MINUTE
  customThresholds:
    com.mtakaki.testcb.TestResource.get.circuitBreaker: 0.2

To register the bundle in the application:

public class MyApp extends Application {
    public static void main(final String[] args) throws Exception {
        new MyApp().run(args);
    }

    private final CircuitBreakerBundle<MyAppConfiguration> circuitBreakerBundle = new CircuitBreakerBundle<MyAppConfiguration>() {
        @Override
        protected CircuitBreakerConfiguration getConfiguration(
                final MyAppConfiguration configuration) {
            return configuration.getCircuitBreaker();
        }
    };

    @Override
    public void initialize(final Bootstrap<MyAppConfiguration> bootstrap) {
        bootstrap.addBundle(this.circuitBreakerBundle);
    };
    
    @Override
    public void run(final MyAppConfiguration configuration, final Environment environment)
            throws Exception {
        environment.jersey().register(new TestResource());
    }
}

To annotate the resource:

@Path("/test")
public class TestResource {
    @GET
    @CircuitBreaker
    public Response get() throws Exception {
        throw new Exception("We want this to fail");
    }

    @GET
    @Path("/custom")
    @CircuitBreaker(name = "customName")
    public Response getCustom() throws Exception {
        throw new Exception("We want this to fail");
    }
}

Now the API localhost:8080/test will keep returning 500 Internal Server Error until it reaches 0.5 exceptions per second (the rate set in our configuration) looking at the 1 minute average (also set in our configuration). Once that happens you will start getting 503 Service Unavailable. After a couple of seconds the rate will decrease, even if you keep hitting the service and getting 503 responses, and you will be getting 500 once again.

The meter is available in the metrics page under the admin port like any other meter. The circuitBreaker one measures the exceptions in the API, while circuiteBreaker.openCircuit measures the requests that didn't hit your API due to the circuit being open. The latter is only available from version 0.0.3.

  "meters" : {
    "com.mtakaki.testcb.TestResource.get.circuitBreaker" : {
      "count" : 51,
      "m15_rate" : 0.055135750452891936,
      "m1_rate" : 0.564668417659197,
      "m5_rate" : 0.15659880505693252,
      "mean_rate" : 1.1303494869953181,
      "units" : "events/second"
    },
    "com.mtakaki.testcb.TestResource.get.circuitBreaker.openCircuit" : {
      "count" : 29,
      "m15_rate" : 0.03204704240331378,
      "m1_rate" : 0.44614897600789627,
      "m5_rate" : 0.09510333717433071,
      "mean_rate" : 0.8154557050860357,
      "units" : "events/second"
    }
  }

Maven

The library is available at the maven central, so just add dependency to pom.xml:

<dependencies>
  <dependency>
    <groupId>com.github.mtakaki</groupId>
    <artifactId>dropwizard-circuitbreaker</artifactId>
    <version>2.0.0</version>
  </dependency>
</dependencies>

Benchmark

tl;dr: Circuit breaker is very lean and there's barely any impact on performance.

Benchmark tests were executed to assess if there is any cost of running an API with the circuit breaker always verifying if the circuit is open, before piping the request through. These tests were executed with these specs:

  • 30 concurrent clients
  • 2,000 requests

On average, without circuit breaker the benchmark test reached 179.97 requests/second. While with circuit breaker it reached 180.77 requests/second.

Failing API

With a constantly failing API, when using the circuit breaker it got 97.40 requests/second, while without using the circuit breaker it got 92.29 requests/second. On the other hand, out of the 2,000 requests, 1,396 requests returned 503 Service Unavailable status.

The metric CircuitBreakerApplicationEventListener.getCircuitBreakerName shows how much overhead the circuit breaker adds to the requests. The average overhead, during these tests, were way below 1ms per request.

  "timers" : {
    "com.github.mtakaki.dropwizard.circuitbreaker.jersey.CircuitBreakerApplicationEventListener.getCircuitBreakerName" : {
      "count" : 4015,
      "max" : 0.001024921,
      "mean" : 8.349680896258536E-6,
      "min" : 1.038E-6,
      "p50" : 4.683E-6,
      "p75" : 7.406000000000001E-6,
      "p95" : 1.6315000000000002E-5,
      "p98" : 2.0050000000000003E-5,
      "p99" : 2.7683000000000002E-5,
      "p999" : 6.15457E-4,
      "stddev" : 3.60241125613854E-5,
      "m15_rate" : 6.589688969963449,
      "m1_rate" : 13.102701736894172,
      "m5_rate" : 11.54464183938005,
      "mean_rate" : 30.191455659575904,
      "duration_units" : "seconds",
      "rate_units" : "calls/second"
    }
}
You might also like...

Saga pattern with Java = order - payment - stock microservices are ready to use

Saga pattern with Java => order -> payment -> stock microservices are ready to use

Order_Payment_Stock_Saga_Pattern Saga pattern with Java = order - payment - stock microservices are ready to use Docker-compose.yaml You can see th

Dec 27, 2022

ObjectiveSQL is an ORM framework in Java based on ActiveRecord pattern

ObjectiveSQL is an ORM framework in Java based on ActiveRecord pattern

ObjectiveSQL is an ORM framework in Java based on ActiveRecord pattern, which encourages rapid development and clean, codes with the least, and convention over configuration.

Dec 28, 2022

JavaFX micro-framework that follows MVVM Pattern with Google Guice dependency Injection

ReactiveDeskFX (JavaFX and Google Guice MVVM Pattern micro-framework) JavaFX micro-framework to develop very fast JavaFX components with minimal code

Jan 9, 2022

Demo Repo for our CDC-based Strangler Fig Pattern Session @ VoxxedDays Romania 2021

Strangler Fig Pattern Demo Build applications Before being able to spin up the docker-compose based demo environment please make sure to successfully

Feb 20, 2022

Design patterns implemented in Java

Design patterns implemented in Java

Design patterns implemented in Java Read in different language : CN, KR, FR, TR, AR Introduction Design patterns are the best formalized practices a p

Dec 31, 2022

Design patterns implemented in Java

Design patterns implemented in Java

Design patterns implemented in Java Read in different language : CN, KR, FR, TR, AR Introduction Design patterns are the best formalized practices a p

Jan 2, 2023

Creational design patterns written in Java

Java Design Patterns Creational design patterns implementation: Singleton, Factory Method, Builder written in Java. Getting Started No additional step

Mar 7, 2022

Spring Domain Driven Design Boilerplate

Spring Domain Driven Design Boilerplate

Spring Domain Driven Design Boilerplate This project describes some product operations such as create and get, also covered by Domain Driven Design on

Dec 29, 2022

شرح الـ Design Patterns باللغة العربية

بسم الله الرحمن الرحيم السلام عليكم ورحمة الله وبركاته تعلم نماذج التصميم باللغة العربية إن شاءالله نبدأ سلسلة بسيطة لشرح الـ Design Pattern باللغة ال

Feb 3, 2022

Java Design Patterns code examples

Java Design Patterns code examples Behavioral In software engineering, behavioral design patterns are design patterns that identify common communicati

Jun 29, 2022

Team project within the course of Software System Design and Analysis.

InnoBookCrossing - Application for sharing books at Innopolis Description The application is designed to help people share books with each other. All

Oct 22, 2022

A collection of design patterns implemented in Java

Design Patterns A collection of design patterns implemented in Java and referenced from this book: Design Patterns: Elements of Reusable Object-Orient

Sep 5, 2022

Design Patterns: Elements of Reusable Object-Oriented Software

GoF Design Patterns Design Patterns: Elements of Reusable Object-Oriented Software Task 싱글톤패턴 싱글톤 패턴 구현 방법을 깨뜨리는 방법 리플렉션을 통해 싱글톤 패턴을 깨뜨리다 역직렬화를 통해 싱글톤

Jul 19, 2022

Modular and customizable Material Design UI components for Android

Material Components for Android Material Components for Android (MDC-Android) help developers execute Material Design. Developed by a core team of eng

Jan 3, 2023

A quiz app with great layout design, dynamic questions using firebase and what not....

A quiz app with great layout design, dynamic questions using firebase and what not....

AndroidQuizApp An android quiz app created using Android Studio with our language JAVA that has great layout design, dynamic questions using firebase

Dec 30, 2022

This project was created as a simple example to show how we can implement the hexagonal architecture(software design) proposed by Netflix.

This project was created as a simple example to show how we can implement the hexagonal architecture(software design) proposed by Netflix.

Netflix Hexagonal Architecture Table of contents About the project Description Built with Installation Requirements to run Usage information Run Licen

Dec 20, 2022

⭕️ CircleMenu is a simple, elegant UI menu with a circular layout and material design animations

⭕️ CircleMenu is a simple, elegant UI menu with a circular layout and material design animations

⭕️ CircleMenu is a simple, elegant UI menu with a circular layout and material design animations. Android UI library made by @Ramotion

Dec 27, 2022

A sideproject to learn more about object-oriented programming, design patterns and Java meanwhile studying an OOP-course.

MyBank Description A console application that simulates a bank with very simple functions. Potential story could be an employee using this application

Mar 23, 2022
Comments
  • Run benchmarks to assess what is the overhead, if there's any

    Run benchmarks to assess what is the overhead, if there's any

    In order to have a proper idea how lean the library is, we should have some benchmark numbers running with and without the @CircuitBreaker annotation. This should give a better idea if there's any overhead of running this library.

    opened by mtakaki 1
  • Add support to custom threshold in jersey

    Add support to custom threshold in jersey

    The @CircuitBreaker annotation should support custom thresholds, for those cases when an API must have a different value from the configuration. The main drawback is that changes to the config file won't reflect in those APIs. Maybe it should alert on server startup about APIs with custom thresholds.

    enhancement 
    opened by mtakaki 0
  • Addressing sonarqube review

    Addressing sonarqube review

    Addressing a couple of issues raised by sonarqube:

    1. Throwing a dedicated exception instead of a generic one (OperationException).
    2. Removing redundant static qualifier from enum.
    3. Annotating Operation interface with @FunctionalInterface.
    4. Removing unnecessary parenthesis from lambda expression in CircuitBreakerApplicationEventListener.
    5. Removing not implemented feature (custom threshold).
    opened by mtakaki 0
Releases(2.0.0)
Owner
null
Test project for learning GoF design pattern

DesignPattern Test project for learning GoF design pattern ㅁ개요 객체지향 설계의 교과서라고 불리는 Design Pattern 을 직접 Activity 별로 구현해봤습니다. ㅁ동기 물론 디자인패턴을 몰라도 기능은 얼마든지

null 11 Aug 8, 2022
Human Resource Management Application on JavaFX using MVC Design Pattern

Human-Resource-Management-System-with-JFoenix Human Resource Management Application on JavaFX using MVC Design Pattern Built With Java JavaFX - FXML C

Bahadır Ünal 0 Mar 18, 2022
LINE 4.1k Jan 2, 2023
Parallel boolean circuit evaluation

splitmap This library builds on top of RoaringBitmap to provide a parallel implementation of boolean circuits (multidimensional filters) and arbitrary

Richard Startin 18 Aug 17, 2022
LINE 4.1k Dec 31, 2022
Automatic generation of the Builder pattern for Java

FreeBuilder Automatic generation of the Builder pattern for Java 1.8+ The Builder pattern is a good choice when designing classes whose constructors o

inferred.org 797 Dec 19, 2022
Java 8 annotation processor and framework for deriving algebraic data types constructors, pattern-matching, folds, optics and typeclasses.

Derive4J: Java 8 annotation processor for deriving algebraic data types constructors, pattern matching and more! tl;dr Show me how to write, say, the

null 543 Nov 23, 2022
Java 8 annotation processor and framework for deriving algebraic data types constructors, pattern-matching, folds, optics and typeclasses.

Derive4J: Java 8 annotation processor for deriving algebraic data types constructors, pattern matching and more! tl;dr Show me how to write, say, the

null 543 Nov 23, 2022
an Application Framework for implementing the MVVM Pattern with JavaFX

mvvmFX is an application framework which provides you necessary components to implement the MVVM pattern with JavaFX. MVVM is the enhanced version of

Alexander Casall 438 Dec 28, 2022
Spring Boot DTO Example Tutorial | Data Transfer Object Pattern

springboot-dto-tutorial Spring Boot DTO Example Tutorial | Data Transfer Object Pattern at https://youtu.be/THv-TI1ZNMk Spring Boot DTO Tutorial - Ent

Ramesh Fadatare 20 Nov 16, 2022