Resilience4j Retry – 记录客户端的重试尝试?

huangapple go评论63阅读模式
英文:

Resilience4j Retry - logging retry attempts from client?

问题

这是否可能通过resilience4j在客户端上记录重试尝试?

也许可以通过某种配置或设置来实现。

目前,我正在使用基于Spring Boot Webflux的resilience4j 基于注解的

它的表现很出色,这个项目很棒。

虽然我们在服务器端记录服务器日志,以查看由于重试而进行了相同的http调用(我们记录时间、客户端IP、请求ID等),但是否可能在客户端也记录日志?

我期望看到类似于“Resilience4j - 客户端:第1次尝试失败,原因是someException,正在第2次尝试。第2次尝试因someException失败,正在第3次尝试。第3次尝试成功!”之类的内容。

类似这样的内容。是否有某个属性、某种配置、某种设置,可以帮助轻松实现这一点?而不需要添加太多样板代码。

@RestController
public class TestController {

    private final WebClient webClient;

    public TestController(WebClient.Builder webClientBuilder) {
        this.webClient = webClientBuilder.baseUrl("http://localhost:8443/serviceBgreeting").build();
    }

    @GetMapping("/greeting")
    public Mono<String> greeting() {
        System.out.println("Greeting method is invoked ");
        return someRestCall();
    }

    @Retry(name = "greetingRetry")
    public Mono<String> someRestCall() {
        return this.webClient.get().retrieve().bodyToMono(String.class);
    }
}

谢谢

英文:

Is it possible to log retries attempts on client side with resilience4j please?

Maybe via some kind of configuration, or settings.

Currently, I am using resilience4j with Spring boot Webflux annotation based.

It is working great, the project is amazing.

While we put server logs on server side, to see that a same http call has been made due to a retry (we log time, client IP, request ID, etc...) Would I be possible to have client side logs?

I was expecting to see something like "Resilience4j - client side: 1st attempt failed because of someException, retying with attend number 2. 2nd attempt failed because of someException, retying with attend number 3. 3rd attempt successful!"

Something like that. Is there a property, some config, some setup, that can help to do this easily please? Without adding too much boiler code.

@RestController
public class TestController {

    private final WebClient webClient;

    public TestController(WebClient.Builder webClientBuilder) {
        this.webClient = webClientBuilder.baseUrl(&quot;http://localhost:8443/serviceBgreeting&quot;).build();
    }

    @GetMapping(&quot;/greeting&quot;)
    public Mono&lt;String&gt; greeting() {
        System.out.println(&quot;Greeting method is invoked &quot;);
        return someRestCall();
    }

    @Retry(name = &quot;greetingRetry&quot;)
    public Mono&lt;String&gt; someRestCall() {
        return this.webClient.get().retrieve().bodyToMono(String.class);
    }

}

Thank you

答案1

得分: 6

幸运的是(或者不幸的是),这里有一个未记录的功能 :)

您可以添加一个RegistryEventConsumer Bean,以便向任何重试实例添加事件消费者。

```java
@Bean
public RegistryEventConsumer<Retry> myRetryRegistryEventConsumer() {

    return new RegistryEventConsumer<Retry>() {
        @Override
        public void onEntryAddedEvent(EntryAddedEvent<Retry> entryAddedEvent) {
            entryAddedEvent.getAddedEntry().getEventPublisher()
               .onEvent(event -> LOG.info(event.toString()));
        }

        @Override
        public void onEntryRemovedEvent(EntryRemovedEvent<Retry> entryRemoveEvent) {

        }

        @Override
        public void onEntryReplacedEvent(EntryReplacedEvent<Retry> entryReplacedEvent) {

        }
    };
}

日志条目如下所示:

2020-10-26T13:00:19.807034700+01:00[Europe/Berlin]:重试'backendA',等待PT0.1S,直到尝试'1'。上次尝试失败,异常为'org.springframework.web.client.HttpServerErrorException: 500 这是一个远程异常'。

2020-10-26T13:00:19.912028800+01:00[Europe/Berlin]:重试'backendA',等待PT0.1S,直到尝试'2'。上次尝试失败,异常为'org.springframework.web.client.HttpServerErrorException: 500 这是一个远程异常'。

2020-10-26T13:00:20.023250+01:00[Europe/Berlin]:重试'backendA'记录了一次失败的重试尝试。重试尝试次数:'3'。放弃重试。上次异常为:'org.springframework.web.client.HttpServerErrorException: 500 这是一个远程异常'。
英文:

Fortunately (or unfortunately) there is an undocumented feature Resilience4j Retry – 记录客户端的重试尝试?

You can add a RegistryEventConsumer Bean in order to add event consumers to any Retry instance.

    @Bean
    public RegistryEventConsumer&lt;Retry&gt; myRetryRegistryEventConsumer() {

        return new RegistryEventConsumer&lt;Retry&gt;() {
            @Override
            public void onEntryAddedEvent(EntryAddedEvent&lt;Retry&gt; entryAddedEvent) {
                entryAddedEvent.getAddedEntry().getEventPublisher()
                   .onEvent(event -&gt; LOG.info(event.toString()));
            }

            @Override
            public void onEntryRemovedEvent(EntryRemovedEvent&lt;Retry&gt; entryRemoveEvent) {

            }

            @Override
            public void onEntryReplacedEvent(EntryReplacedEvent&lt;Retry&gt; entryReplacedEvent) {

            }
        };
    }

Log entry look as follows:

2020-10-26T13:00:19.807034700+01:00[Europe/Berlin]: Retry &#39;backendA&#39;, waiting PT0.1S until attempt &#39;1&#39;. Last attempt failed with exception &#39;org.springframework.web.client.HttpServerErrorException: 500 This is a remote exception&#39;.

2020-10-26T13:00:19.912028800+01:00[Europe/Berlin]: Retry &#39;backendA&#39;, waiting PT0.1S until attempt &#39;2&#39;. Last attempt failed with exception &#39;org.springframework.web.client.HttpServerErrorException: 500 This is a remote exception&#39;.

2020-10-26T13:00:20.023250+01:00[Europe/Berlin]: Retry &#39;backendA&#39; recorded a failed retry attempt. Number of retry attempts: &#39;3&#39;. Giving up. Last exception was: &#39;org.springframework.web.client.HttpServerErrorException: 500 This is a remote exception&#39;.

答案2

得分: 4

在网络上,如果你在Google搜索 "resilience4j retry example logging",关于这方面的信息似乎很丰富。我找到了以下作为潜在解决方案:

RetryConfig config = RetryConfig.ofDefaults();
RetryRegistry registry = RetryRegistry.of(config);
Retry retry = registry.retry("flightSearchService", config);

...

Retry.EventPublisher publisher = retry.getEventPublisher();
publisher.onRetry(event -> System.out.println(event.toString()));

在这里,你可以注册一个回调以在 Retry 发生时收到事件通知。这段代码来自 "https://reflectoring.io/retry-with-resilience4j"。

英文:

There seems to be a lot of information about this on the web if you Google for "resilience4j retry example logging". I found this as a potential solution:

RetryConfig config = RetryConfig.ofDefaults();
RetryRegistry registry = RetryRegistry.of(config);
Retry retry = registry.retry(&quot;flightSearchService&quot;, config);

...

Retry.EventPublisher publisher = retry.getEventPublisher();
publisher.onRetry(event -&gt; System.out.println(event.toString()));

where you can register a callback to get an event whenever a Retry occurs. This. came from "https://reflectoring.io/retry-with-resilience4j".

答案3

得分: 0

使用application.properties配置,并使用@Retry注解,我成功地获得了一些输出。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import io.github.resilience4j.retry.RetryRegistry;
import io.github.resilience4j.retry.annotation.Retry;

@Service
public class MyService {
	private static final Logger LOG = LoggerFactory.getLogger(MyService.class);

	public MyService(RetryRegistry retryRegistry) {
        // 获取所有
        retryRegistry.getAllRetries()
          .forEach(retry -&gt; retry
            .getEventPublisher()
            .onRetry(event -&gt; LOG.info(&quot;{}&quot;, event))
        );

       // 或者单独获取
       retryRegistry
			.retry(&quot;myRetry&quot;)
			.getEventPublisher()
			.onRetry(event -&gt; LOG.info(&quot;{}&quot;, event));
	}

    @Retry(name = &quot;myRetry&quot;)
    public void doSomething() {
		throw new RuntimeException(&quot;它失败了&quot;);
    }
}

例如:

2021-03-31T07:42:23 [http-nio-8083-exec-1] INFO  [myService] - 2021-03-31T07:42:23.228892500Z[UTC]: Retry &#39;myRetry&#39;, 等待 PT1S 直到尝试 &#39;1&#39;。上一次尝试失败,异常为 &#39;java.lang.RuntimeException: 它失败了&#39;。
2021-03-31T07:42:24 [http-nio-8083-exec-1] INFO  [myService] - 2021-03-31T07:42:24.231504600Z[UTC]: Retry &#39;myRetry&#39;, 等待 PT2S 直到尝试 &#39;2&#39;。上一次尝试失败,异常为 &#39;java.lang.RuntimeException: 它失败了&#39;。
英文:

Configured with application.properties, and using the @Retry annotation, I managed to get some output with

resilience4j.retry.instances.myRetry.maxAttempts=3
resilience4j.retry.instances.myRetry.waitDuration=1s
resilience4j.retry.instances.myRetry.enableExponentialBackoff=true
resilience4j.retry.instances.myRetry.exponentialBackoffMultiplier=2
resilience4j.retry.instances.myRetry.retryExceptions[0]=java.lang.Exception
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import io.github.resilience4j.retry.RetryRegistry;
import io.github.resilience4j.retry.annotation.Retry;

@Service
public class MyService {
	private static final Logger LOG = LoggerFactory.getLogger(MyService.class);

	public MyService(RetryRegistry retryRegistry) {
        // all
        retryRegistry.getAllRetries()
          .forEach(retry -&gt; retry
            .getEventPublisher()
            .onRetry(event -&gt; LOG.info(&quot;{}&quot;, event))
        );

       // or single
       retryRegistry
			.retry(&quot;myRetry&quot;)
			.getEventPublisher()
			.onRetry(event -&gt; LOG.info(&quot;{}&quot;, event));
	}

    @Retry(name = &quot;myRetry&quot;)
    public void doSomething() {
		throw new RuntimeException(&quot;It failed&quot;);
    }
}

eg.

2021-03-31T07:42:23 [http-nio-8083-exec-1] INFO  [myService] - 2021-03-31T07:42:23.228892500Z[UTC]: Retry &#39;myRetry&#39;, waiting PT1S until attempt &#39;1&#39;. Last attempt failed with exception &#39;java.lang.RuntimeException: It failed&#39;.
2021-03-31T07:42:24 [http-nio-8083-exec-1] INFO  [myService] - 2021-03-31T07:42:24.231504600Z[UTC]: Retry &#39;myRetry&#39;, waiting PT2S until attempt &#39;2&#39;. Last attempt failed with exception &#39;java.lang.RuntimeException: It failed&#39;.

huangapple
  • 本文由 发表于 2020年10月25日 10:56:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/64519894.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定