簡體   English   中英

Resilience4J Retry 的預期行為是什么?

[英]What is the expected behavior of Resilience4J Retry?

我在 Spring Boot 項目中使用 Resilience4J 來調用 REST 客戶端,如下所示:

@Retry(name = "customerService")
public Customer getCustomer(String customerNumber) {
    restTemplate.exchange("https://customer-service.net", HttpMethod.GET, ..., customerNumber);
}

使用此配置:

resilience4j.retry:
    instances:
        customerService:
            maxAttempts: 3
            waitDuration: 10s
            retryExceptions:
                - org.springframework.web.client.HttpServerErrorException

我的期望是,如果調用restTemplate.exchange()並且客戶服務以HttpServerErrorException響應,則在等待 10 秒后將再調用 3 次getCustomer()方法。

然而,這種情況並非如此。

永遠不會再次調用此方法,並立即拋出異常。

看到示例中包含回退方法,我決定添加它,即使我真的不想調用不同的方法,我只想再次調用我的原始方法。

無論如何,我指定了一個回退:

@Retry(name = "customerService", fallback = "customerFb")
public Customer getCustomer(String customerNumber) {
    return getCustomer();
}

private Customer customerFb(String customerNumber, HttpServerErrorException ex) {
    log.error("Could not retrieve customer... retrying...");
    return getCustomer();
}

private Customer getCustomer(String customerNumber) {
    return restTemplate.exchange("https://customer-service.net", HttpMethod.GET, ..., customerNumber);
}

現在,我看到正在重試回退方法,但是,每次都會拋出 HttpServerErrorException,這意味着消費者將收到一個異常作為對他們調用的響應。

我的問題是:

是否需要實施回退方法才能使重試功能起作用?

拋出異常是預期的行為嗎? 難道我做錯了什么? 在進行所有重試嘗試之前,我不希望此服務的調用者收到異常。

謝謝

問:是否需要實施回退方法才能使重試功能起作用?

回答:不,回退在 Resilience4J 重試功能中是可選的

Resilience4J Retry行為

  1. 在啟動時,彈性重試從 application.properties/yml 加載配置,如果配置否則將使用文檔中提到的默認值進行初始化。

  2. 當使用@Retry 注釋的方法被調用時,它將處於重試監視器下。

  3. 如果明確配置了屬性resilience4j.retry.instances.<instance name>.retryExceptions那么只有配置的異常才會被視為失敗,並且只會為這些失敗觸發重試,對於其余的異常,它在沒有重試的情況下表現正常特征。

  4. 當在@retry注釋方法下發生預期的異常時,它不會記錄有關異常的任何信息,但會根據配置的maxAttempts屬性重試相同的方法。 maxAttempts屬性的默認值為3 在 maxAttempts 之后,它會拋出異常並且可以在日志中看到。

  5. 還有像waitDurationintervalFunctionignoreExceptions .. e.tc 這樣的屬性可以顯式配置。 有關更多信息,請查看文檔鏈接。

  6. 要在使用@retry注釋的方法中實際查看異常事件期間發生的情況,請啟用 RetryRegistry 事件使用者以打印接收到的事件。

RetryRegistry 事件偵聽器的示例代碼:

package com.resilience.retry.config;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import io.github.resilience4j.retry.RetryRegistry;
import lombok.extern.slf4j.Slf4j;

@Component
@Slf4j
public class RetryRegistryEventListener {

    @Autowired
    private RetryRegistry registry;


    @PostConstruct
    public void postConstruct() {
        //registry.retry(<resilience retry instance name>)
        registry.retry("sample-api").getEventPublisher()
                .onRetry(ev -> log.info("#### RetryRegistryEventListener message: {}", ev));
    }
}

示例日志:

2021-11-01 14:55:12.337  INFO 18176 --- [nio-8080-exec-1] c.r.retry.controller.RetryController     : Sample Api call receieved
2021-11-01 14:55:12.345  INFO 18176 --- [nio-8080-exec-1] c.r.r.config.RetryRegistryEventListener  : #### RetryRegistryEventListener message: 2021-11-01T14:55:12.344325600+05:30[Asia/Calcutta]: Retry 'sample-api', waiting PT10S until attempt '1'. Last attempt failed with exception 'org.springframework.web.client.HttpServerErrorException: 500 INTERNAL_SERVER_ERROR'.
2021-11-01 14:55:12.350  INFO 18176 --- [nio-8080-exec-1] c.r.retry.controller.RetryController     : messsage: 2021-11-01T14:55:12.344325600+05:30[Asia/Calcutta]: Retry 'sample-api', waiting PT10S until attempt '1'. Last attempt failed with exception 'org.springframework.web.client.HttpServerErrorException: 500 INTERNAL_SERVER_ERROR'.
2021-11-01 14:55:22.359  INFO 18176 --- [nio-8080-exec-1] c.r.retry.controller.RetryController     : Sample Api call receieved
2021-11-01 14:55:22.360  INFO 18176 --- [nio-8080-exec-1] c.r.r.config.RetryRegistryEventListener  : #### RetryRegistryEventListener message: 2021-11-01T14:55:22.360672900+05:30[Asia/Calcutta]: Retry 'sample-api', waiting PT10S until attempt '2'. Last attempt failed with exception 'org.springframework.web.client.HttpServerErrorException: 500 INTERNAL_SERVER_ERROR'.
2021-11-01 14:55:22.361  INFO 18176 --- [nio-8080-exec-1] c.r.retry.controller.RetryController     : messsage: 2021-11-01T14:55:22.360672900+05:30[Asia/Calcutta]: Retry 'sample-api', waiting PT10S until attempt '2'. Last attempt failed with exception 'org.springframework.web.client.HttpServerErrorException: 500 INTERNAL_SERVER_ERROR'.

@FerdTurgusen:我相信您的代碼中存在一些錯誤,否則它會正常工作。 根據問題中的給定信息,我無法准確找到問題。 因此,我創建了一個帶有彈性4j示例的示例彈簧靴,復制了您的問題並且對我來說工作正常,因此上傳到Github以供您參考。 我建議您添加 RetryRegistryEventListener 類並在事件日志中查找問題,如果仍未解決請分享事件監聽器日志。

Github 參考帶有彈性 4j 重試項目的示例 spring-boot

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM