带有 RetryTemplate 最佳实践或建议的千分尺

问题描述

我正在使用 micrometer java 库来收集指标,例如某些方法的执行时间等。 经过一段时间的思考,我对如何在使用 retryTemplate 时正确收集指标感到困惑。

示例:

// I have more methods like delete,search,etc where we can face the same issue
public void upsertDocument(WalRecord walRecord) { 
...
retryTemplate.execute(context ->
  arangoInitService.getarangoDb()
    .collection(walRecord.getBaseType())
    .insertDocument(data,upsertOptions));
...
}

因此,这里我们有不同的选项来收集“计时器”指标。

  1. 使用注解@Timed
@Timed
public void upsertDocument(WalRecord walRecord) {...}

看起来很简单,但我不喜欢它,因为在重试的情况下会总结执行时间。

  1. 使用千分尺库的 Timer 类,类似的东西
retryTemplate.execute(context -> {
...
Timer.Sample sample = Timer.start(registry);
retryTemplate.execute(context -> {
  arangoInitService.getarangoDb()
    .collection(walRecord.getBaseType())
    .insertDocument(data,upsertOptions)
sample.stop(registry.timer("my.timer","response",response.status()));
});
...
}

现在,即使发生重试,我们也收集了正确的时间,但看起来我们不会收集失败的 insertDocument() 操作的指标!

  1. 我来到了下一个解决方案。使用 next 包装器可以收集任何调用的指标
public  <T,E extends Throwable> T inTimerWithRetry(String metricName,RetryTemplate retryTemplate,MetricCoveredCallable<T> callable) throws E {
    T res;
    res = retryTemplate.execute(context -> {
        String exception = "none";
        Timer.Sample sample = null;
        if (registry != null) {
            sample = Timer.start(registry);
        }
        try {
            return callable.call();
        } catch (Throwable e) {
            exception = e.getClass().getSimpleName();
            throw (E) e;
        } finally {
            if (sample != null) {
                sample.stop(Timer.builder(metricName)
                        .tags("exception",exception)
                        .register(registry));
            }
        }
    });
    return res;
}

这里是我的问题,你怎么看

  1. 做这样的包装值得吗?
  2. 有更好的解决方案吗?欢迎您提出任何改进建议
  3. 也许我做错了什么,并无缘无故地让它变得过于复杂?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)