[JAVA] Let's make a circuit breaker for back-end service using Actuator of Spring Boot (Part 1)

Prerequisites

When developing a system, it is sometimes unreasonable to say, "Even if the backend service breaks down and starts returning an error, it should work nicely so that the entire system does not become unstable." right?

In such a case, it is troublesome to think about the operation on your own, so I experimented with the possibility of using the Spring Boot function to make it a circuit breaker.

In the end, I want to make it work well on AWS, but the first half is the implementation method.

Preparing for Spring Boot

For the time being, it's good if it works as a web application with a minimum, so create an empty starter project from the template.

In addition to the default, set the following dependencies in pom.xml.

pom.xml


    <dependencies>
        ……
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        ……
    </dependencies>

RestController is not the main part of this time, so it's a textbook. With the minimum configuration, it looks like the following.

WebController.java


package com.example;
 
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
@RestController
public class WebController {
 
  @RequestMapping("/hello")
  public String hello() {
    return "hello()";
  }
   
}

Additional definition of health check to backend service

From here, Spring Boot documentation While reading.

Register the health check for the backend service as a custom health check. This time, I'm experimenting with the backend service as a Lambda function for easy control, so Lambda is included in the name of the health check, but if you can change it to any name you like.

Implement the Health Indicator interface as follows. By doing this, it seems that it will be automatically registered in the bean at startup. I do not understand the detailed mechanism. I have to study properly.

LambdaHealthIndicator.java


package com.example;

import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.actuate.health.Health;
import org.springframework.stereotype.Component;
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.IOException;

@Component
public class LambdaHealthIndicator implements HealthIndicator {

  @Override
  public Health health() {
    int statusCode = check();
    if (statusCode != HttpURLConnection.HTTP_OK) {
      return Health.down().withDetail("HTTP Request Error", statusCode).build();
    } else {
      return Health.up().withDetail("HTTP Request Success", statusCode).build();
    }
  }
    
  private int check(){
    String strUrl = "Lambda function hanging ALB/NLB/API Gateway URL";
    URL url = null;
    HttpURLConnection  urlConn = null;
    int statusCode = 200;

    try {
      url = new URL(strUrl);
      urlConn = (HttpURLConnection) url.openConnection();
      urlConn.setRequestMethod("GET");
      urlConn.connect();
      statusCode = urlConn.getResponseCode();	
    } catch (IOException e) {
      e.printStackTrace();
      statusCode = 503;
    } finally {
      if (urlConn != null) {
        urlConn.disconnect();
      }
    }
    return statusCode;
  }
}

By the way, with this alone, in the default display of Acutuator, even if you access / actuator / health

{"status":"UP"}

Will only return. It is necessary to edit the application properties as follows.

application.properties


management.endpoint.health.show-details=always
management.health.defaults.enabled=false
management.health.lambda.enabled=true

The first line is an option to display the details of the health check. If the second line is true, diskspace is also displayed and it is hard to see, so I will disable it in this article. The third line enables the added `` `LambdaHealthIndicator```. As mentioned in the documentation, the Health Indicator prefix seems to be treated as a setting.

Experiment

When you start the above app and access http: // localhost: 8080 / actuator / health,

{"status":"UP","components":{"lambda":{"status":"UP","details":{"HTTP Request Success":200}}}}

Is displayed. Here, if you perform throttling (= reservation for simultaneous execution: 0) from the setting of the Lambda function on the back end and make it a state where 502 response is returned from ALB,

{"status":"DOWN","components":{"lambda":{"status":"DOWN","details":{"HTTP Request Error":502}}}}

And the error is detected properly. If you check the header with Chrome's developer tools,

キャプチャ3.PNG

The response code is also 503, so if you point the health check here, you can treat it as a circuit breaker!

Recommended Posts

Let's make a circuit breaker for back-end service using Actuator of Spring Boot (Part 1)
Let's make a book management web application with Spring Boot part1
How to make a hinadan for a Spring Boot project using SPRING INITIALIZR
Let's make a book management web application with Spring Boot part3
Let's make a book management web application with Spring Boot part2
Let's make a simple API with EC2 + RDS + Spring boot ①
Let's make a communication application in LAN Part 2 Display a window using JavaFX / Wait for socket reception
Let's write a test code for login function in Spring Boot
Java beginner tried to make a simple web application using Spring Boot
WebMvcConfigurer Memorandum of Understanding for Spring Boot 2.0 (Spring 5)
Introducing the Spring Boot Actuator, a function that makes the operation of Spring Boot applications easier.
[FCM] Implementation of message transmission using FCM + Spring boot
Let's make a shopping site using stripe! (Purchase)
Create a Spring Boot application using IntelliJ IDEA
How to write a unit test for Spring Boot 2
Let's make a pseudo model using active_hash ~ Prefecture data ~
Let's make a LINE Bot with Ruby + Sinatra --Part 2
[JUnit 5 compatible] Write a test using JUnit 5 with Spring boot 2.2, 2.3
[Spring Boot] How to create a project (for beginners)
[Java basics] Let's make a triangle with a for statement
Let's make a robot! "A simple demo of Java AWT Robot"
[Introduction to Spring Boot] Submit a form using thymeleaf
A memorandum when creating a REST service with Spring Boot
Let's make a LINE Bot with Ruby + Sinatra --Part 1