+1

Sử dụng Spring Cloud Circuit Breaker trong Microservice - Java springboot

Spring Cloud Circuit Breaker trong Spring cloud là một thư viện quan trong cho phép bạn triển khai mô hình circuit breaker trong các ứng dụng microservices Springboot. Mô hình circuit breaker giúp bảo vệ ứng dụng/dịch vụ của bạn khỏi các dịch vụ phụ thuộc đang bị lỗi hoặc chậm chạp (đang quá tải).

Spring Cloud Circuit Breaker cung cấp một số tính năng chính, bao gồm:

  • Tự động mở mạch: Spring Cloud Circuit Breaker sẽ tự động mở mạch khi một dịch vụ phụ thuộc bị lỗi hoặc chậm chạp. Điều này giúp bảo vệ ứng dụng của bạn khỏi các lỗi tràn lan. Điều này giúp cải thiện độ tin cậy của ứng dụng của bạn.
  • Chế độ chuyển tiếp: Spring Cloud Circuit Breaker cung cấp một chế độ chuyển tiếp cho phép ứng dụng của bạn tiếp tục hoạt động ngay cả khi một dịch vụ phụ thuộc bị lỗi. Giúp cải thiện hiệu suất của ứng dụng của bạn bằng cách tránh gọi các dịch vụ phụ thuộc bị lỗi hoặc chậm chạp.
  • Tích hợp với các công cụ phân tích rủi ro: Spring Cloud Circuit Breaker có thể tích hợp với các công cụ phân tích rủi ro phổ biến, chẳng hạn như Zipkin và Jaeger. Điều này cho phép bạn xem các dữ liệu phân tích rủi ro của ứng dụng của mình trong một giao diện trực quan.

Để sử dụng Spring Cloud Circuit Breaker, bạn cần thêm các phụ thuộc sau vào ứng dụng của mình (ở đây tôi sử dụng maven - pom):

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
    <version>3.1.0</version>
</dependency>

Dưới đây là một ví dụ về cách sử dụng Spring Cloud Circuit Breaker để bảo vệ một yêu cầu HTTP khỏi một dịch vụ phụ thuộc bị lỗi:

@RestController
public class MyController {

    @GetMapping("/hello")
    public String hello() {
        // Tạo một circuit breaker cho dịch vụ phụ thuộc
        CircuitBreaker circuitBreaker = CircuitBreakerFactory.create("greetingService");

        // Thực hiện yêu cầu HTTP
         RestTemplate restTemplate = new RestTemplate();
        String response = circuitBreaker.run(() -> restTemplate.getForObject("http://localhost:8081/greeting", String.class));

        return response;
    }
}

Trong ví dụ này, chúng ta tạo một circuit breaker cho dịch vụ phụ thuộc greetingService. Sau đó, chúng ta sử dụng circuitBreaker.run() để thực hiện yêu cầu HTTP. Nếu dịch vụ phụ thuộc bị lỗi, circuit breaker sẽ mở mạch và yêu cầu sẽ không được thực hiện. Khi yêu cầu HTTP được thực hiện, circuit breaker sẽ kiểm tra trạng thái của dịch vụ phụ thuộc. Nếu dịch vụ phụ thuộc đang hoạt động, circuit breaker sẽ thực hiện yêu cầu HTTP. Nếu dịch vụ phụ thuộc đang bị lỗi, circuit breaker sẽ mở mạch và yêu cầu sẽ không được thực hiện.

Một cách khác bạn có thể sử dụng annotation để sử dụng circuit breaker:

@CircuitBreaker

Annotation này được sử dụng để chỉ định rằng một phương thức được bảo vệ bởi một circuit breaker. Bạn có thể sử dụng annotation này cho các phương thức HTTP. Dưới đây là một ví dụ về cách sử dụng annotation @CircuitBreaker:

@RestController
public class MyController {

    @GetMapping("/hello")
    @CircuitBreaker(name = "greetingService")
    public String hello() {
        // Thực hiện yêu cầu HTTP
        RestTemplate restTemplate = new RestTemplate();
        String response = restTemplate.getForObject("http://localhost:8081/greeting", String.class);

        return response;
    }
}

Trong ví dụ này, chúng ta sử dụng annotation @CircuitBreaker để chỉ định rằng phương thức hello() được bảo vệ bởi một circuit breaker có tên là greetingService.

@Fallback

Annotation này được sử dụng để chỉ định phương thức sẽ được gọi khi circuit breaker mở mạch. Bạn có thể sử dụng annotation này cho các phương thức HTTP. Dưới đây là một ví dụ về cách sử dụng annotation @Fallback:

@RestController
public class MyController {

    @GetMapping("/hello")
    @CircuitBreaker(name = "greetingService")
    @Fallback(fallbackMethod = "fallbackHello")
    public String hello() {
        // Thực hiện yêu cầu HTTP
        RestTemplate restTemplate = new RestTemplate();
        String response = restTemplate.getForObject("http://localhost:8081/greeting", String.class);

        return response;
    }

    private String fallbackHello() {
        return "Fallback greeting";
    }
}

Trong ví dụ này, chúng ta sử dụng annotation @Fallback để chỉ định rằng phương thức fallbackHello() sẽ được gọi khi circuit breaker mở mạch.

@CircuitBreakerProperties

Annotation này được sử dụng để cấu hình các thuộc tính của circuit breaker. Bạn có thể sử dụng annotation này cho các phương thức HTTP và các phương thức Spring Cloud khác. Dưới đây là một ví dụ về cách sử dụng annotation @CircuitBreakerProperties:

@RestController
public class MyController {

    @GetMapping("/hello")
    @CircuitBreaker(name = "greetingService",
            circuitBreakerProperties = @CircuitBreakerProperties(
                    threshold = 5,
                    timeout = 1000,
                    failureRateThreshold = 0.5))
    public String hello() {
        // Thực hiện yêu cầu HTTP
        RestTemplate restTemplate = new RestTemplate();
        String response = restTemplate.getForObject("http://localhost:8081/greeting", String.class);

        return response;
    }
}

Trong ví dụ này, chúng ta sử dụng annotation @CircuitBreakerProperties để cấu hình các thuộc tính của circuit breaker, bao gồm:

  • threshold: Số lượng lỗi tối thiểu trước khi circuit breaker mở mạch.
  • timeout: Thời gian tối đa để đợi phản hồi từ dịch vụ phụ thuộc.
  • failureRateThreshold: Tỷ lệ lỗi tối đa trước khi circuit breaker mở mạch.

Ngoài các annotation trên, Spring Cloud Circuit Breaker còn cung cấp một số annotation khác để giúp bạn dễ dàng triển khai circuit breaker trong ứng dụng của mình. Để biết thêm thông tin, các bạn tham khảo tài liệu chính thức của Spring Cloud Circuit Breaker nhé.

Tiếp theo, các bạn có thể cấu hình Circuit Breaker Properties trong file Application.properties. Để làm điều này, bạn cần thêm các thuộc tính sau vào file Application.properties:

  • spring.cloud.circuitbreaker.enabled: Bật hoặc tắt tính năng circuit breaker. Giá trị mặc định là true.
  • spring.cloud.circuitbreaker.circuitBreaker: Cấu hình các thuộc tính của circuit breaker.

Dưới đây là một ví dụ về cách cấu hình Circuit Breaker Properties trong file application.properties:

spring.cloud.circuitbreaker.enabled=true

spring.cloud.circuitbreaker.circuitBreaker.greetingService.threshold=5
spring.cloud.circuitbreaker.circuitBreaker.greetingService.timeout=1000
spring.cloud.circuitbreaker.circuitBreaker.greetingService.failureRateThreshold=0.5

Trong ví dụ này, chúng ta bật tính năng circuit breaker và cấu hình các thuộc tính của circuit breaker cho dịch vụ phụ thuộc greetingService.

Dưới đây là danh sách các thuộc tính của Circuit Breaker Properties:

  • name: Tên của circuit breaker.
  • threshold: Số lượng lỗi tối thiểu trước khi circuit breaker mở mạch.
  • timeout: Thời gian tối đa để đợi phản hồi từ dịch vụ phụ thuộc.
  • failureRateThreshold: Tỷ lệ lỗi tối đa trước khi circuit breaker mở mạch.
  • slidingWindow: Kích thước của cửa sổ trượt.
  • permittedNumberOfCallsInHalfOpenState: Số lượng yêu cầu được phép thực hiện khi circuit breaker ở trạng thái half-open.
  • slowCallRateThreshold: Tỷ lệ lỗi tối đa cho các yêu cầu chậm.
  • slowCallDurationThreshold: Thời gian tối đa cho một yêu cầu chậm.
  • slowCallTimeout: Thời gian tối đa để đợi phản hồi từ một yêu cầu chậm.
  • enableHealthIndicator: Bật hoặc tắt chỉ báo sức khỏe cho circuit breaker. Giá trị mặc định là true.
  • healthIndicatorType: Loại chỉ báo sức khỏe cho circuit breaker. Giá trị mặc định là CIRCUIT_BREAKER.
  • circuitBreakerConfig: Cấu hình chi tiết cho circuit breaker.

Để biết thêm thông tin về các thuộc tính của Circuit Breaker Properties, các bạn tham khảo tài liệu chính thức của Spring Cloud Circuit Breaker nhé.

Và cuối cùng, từ nhưng kiến thức chúng ta đã cùng tìm hiểu từ đầu tới giờ, cùng mình thử áp dụng Circuit Breaker vào mô hình kiến trúc 3 lớp Application - Domain - Architecture layer nhé: Cấu hình file pom.xml Bạn cần thêm 2 dependence này vào nhé:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
    <version>3.1.0</version>
</dependency>

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
    <version>3.1.0</version>
</dependency>

Trong spring-cloud-starter-openfeign cũng có hỗ trợ sử dụng Hystrix để phát hiện lỗi và circuit breaker, tuy nhiên nó chỉ mức đơn giản ít tùy biến. chúng ta sẽ tìm hiểu nó và có sự so sánh với Spring Cloud Circuit Breaker trong bài viết sau của tôi nhé. Trong bài viết này, tôi sử dụng spring-cloud-starter-openfeign để tạo các yêu cầu API đến service khác (trong ví dụ này là "greeting Service")

Tầng architecture layer

Tầng architecture layer là tầng chịu trách nhiệm kết nối với các dịch vụ phụ thuộc. Trong ví dụ này, chúng ta sử dụng feign client để kết nối với một dịch vụ phụ thuộc có tên là greetingService.

@FeignClient("greetingService")
public interface GreetingClient {

    @GetMapping("/greeting")
    String greeting(@RequestParam("name") String name);
}

Tầng domain layer

Tầng domain layer là tầng chịu trách nhiệm thực hiện các logic nghiệp vụ. Trong ví dụ này, chúng ta sử dụng GreetingService để thực hiện logic nghiệp vụ lấy lời chào.

@Service
public class GreetingService {

    private final GreetingClient greetingClient;

    public GreetingService(GreetingClient greetingClient) {
        this.greetingClient = greetingClient;
    }

    public String getGreeting(String name) {
        return greetingClient.greeting(name);
    }

}

Tầng application layer

Tầng application layer là tầng chịu trách nhiệm triển khai Restful API. Trong ví dụ này, chúng ta sử dụng TestGreetingController để triển khai restful api trả về lời chào.

@RestController
public class TestGreetingController {

    private final GreetingService greetingService;

    public GreetingController(GreetingService greetingService) {
        this.greetingService = greetingService;
    }

    @GetMapping("/greeting")
    @CircuitBreaker(name = "greetingService")
    public String greeting(String name) {
        return greetingService.getGreeting(name);
    }
}

Trong ví dụ này, chúng ta sử dụng annotation @CircuitBreaker để chỉ định rằng phương thức greeting() được bảo vệ bởi một circuit breaker có tên là greetingService.

Cấu hình Circuit Breaker Properties

Chúng ta có thể cấu hình các thuộc tính của circuit breaker trong file Application.properties. Trong ví dụ này, chúng ta cấu hình các thuộc tính của circuit breaker như sau:

spring.cloud.circuitbreaker.enabled=true

spring.cloud.circuitbreaker.circuitBreaker.greetingService.threshold=5
spring.cloud.circuitbreaker.circuitBreaker.greetingService.timeout=1000
spring.cloud.circuitbreaker.circuitBreaker.greetingService.failureRateThreshold=0.5

Trong ví dụ này, chúng ta bật tính năng circuit breaker và cấu hình các thuộc tính của circuit breaker cho dịch vụ phụ thuộc greetingService. Khi chúng ta thực hiện yêu cầu HTTP đến endpoint /greeting, circuit breaker sẽ kiểm tra trạng thái của dịch vụ phụ thuộc greetingService. Nếu dịch vụ phụ thuộc đang hoạt động, circuit breaker sẽ thực hiện yêu cầu HTTP. Nếu dịch vụ phụ thuộc bị lỗi, circuit breaker sẽ mở mạch và yêu cầu HTTP sẽ không được thực hiện. Chúng ta có thể xem trạng thái của circuit breaker bằng cách sử dụng các công cụ phân tích rủi ro phổ biến, chẳng hạn như Zipkin và Jaeger.

Kết quả Cảm ơn các bạn đã đồng hành cùng tôi trong bài viết này. Rất mong các bạn có thể phát triển hơn nữa, luôn tìm tòi nhưng kỹ thuật mới để áp dụng vào sản phẩm của mình để đạt được hiệu quả cao nhất.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí