Java 如何使用弹簧靴2和千分尺测量服务方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/48704789/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to measure service methods using spring boot 2 and micrometer
提问by Christian Frommeyer
I started my first project on Spring Boot 2 (RC1). Thanks to the already good documentation this has not been to hard coming from Spring Boot 1.x.
我在 Spring Boot 2 (RC1) 上开始了我的第一个项目。多亏了已经很好的文档,从 Spring Boot 1.x 开始这并不难。
However now that I want to integrate metrics I'm stumbeling. As far as I was able to find currently there is only documentation for the metrics shipped by default. But I'd like to also measure service level execution time as well as the time used in dynamodb.
但是,现在我想集成指标,我很困惑。据我所知,目前只有默认提供的指标的文档。但我还想测量服务级别执行时间以及在 dynamodb 中使用的时间。
EDITI'm looking for a solution using Micrometer, the library used in the new actuator library shipped with spring-boot 2.
编辑我正在寻找使用 Micrometer 的解决方案,该库在 spring-boot 2 附带的新执行器库中使用。
Is there any guide on how this should be done? From thisI read that there is no easy annotation based solution for arbitrary spring beans yet. Could s.o. give me an example / link to documentation on how a method like below could be metered?
有没有关于如何做到这一点的指南?从这里我读到,对于任意 spring bean 还没有简单的基于注释的解决方案。可以给我一个示例/链接到有关如何计量如下方法的文档吗?
@Service
@Timed
public class MyService {
public void doSomething() {
...;
}
}
采纳答案by mweirauch
Here's a little sample which should get you going. There's more variants to Timer.record()
which aren't shown here. (Also: Field injection only used for brevity.)
You don't have to put the called methods name into a tag. You can also make it part of the metric name itself. Just wanted to show what you could do.
这是一个小示例,应该可以帮助您前进。Timer.record()
此处未显示更多变体。(另外:字段注入只是为了简洁起见。)您不必将被调用的方法名称放入标签中。您还可以将其作为指标名称本身的一部分。只是想展示你能做什么。
Update 2018-03-12:As of Micrometer 1.0.0
a TimedAspect
has been introduced so that you can also use the @Timed
annotation. For now you need to register the Bean
yourself. (You need to be cautious though when you have custom @Timed
annotations on your Spring-MVC or Jersey resources.) This was already mentioned by Michal Stepanin a follow-up answer.
2018 年 3 月 12 日更新:已引入As of Micrometer 1.0.0
a,TimedAspect
以便您也可以使用@Timed
注释。现在你需要Bean
自己注册。(当您@Timed
在 Spring-MVC 或 Jersey 资源上有自定义注释时,您需要谨慎。)Michal Stepan在后续回答中已经提到了这一点。
package io.github.mweirauch.micrometered.eval;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import io.micrometer.core.annotation.Timed;
import io.micrometer.core.aop.TimedAspect;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import io.micrometer.core.instrument.Timer.Sample;
@Configuration
@EnableAspectJAutoProxy
public class TimingStuff {
@Service
static class MyService {
@Autowired
private MeterRegistry registry;
public void helloManual() {
// you can keep a ref to this; ok to call multiple times, though
Timer timer = Timer.builder("myservice").tag("method", "manual").register(registry);
// manually do the timing calculation
long start = System.nanoTime();
doSomething();
timer.record(System.nanoTime() - start, TimeUnit.NANOSECONDS);
}
public void helloSupplier() {
Timer timer = Timer.builder("myservice").tag("method", "supplier").register(registry);
// execution of the method is timed internally
timer.record(() -> doSomething());
}
public void helloSample() {
Timer timer = Timer.builder("myservice").tag("method", "sample").register(registry);
// records time taken between Sample creation and registering the
// stop() with the given Timer
Sample sample = Timer.start(registry);
doSomething();
sample.stop(timer);
}
// TimedAspect adds "class" and "method" tags
@Timed(value = "myservice.aspect")
public void helloAspect() {
doSomething();
}
private void doSomething() {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
//
}
}
}
@Autowired
private MyService myService;
@Bean
TimedAspect timedAspect(MeterRegistry registry) {
return new TimedAspect(registry);
}
@Scheduled(fixedRate = 1000)
public void postConstruct() {
myService.helloManual();
myService.helloSupplier();
myService.helloSample();
myService.helloAspect();
}
}
In case you go for Prometheus, you'd end up with something like that:
如果你选择 Prometheus,你最终会得到这样的结果:
# HELP myservice_seconds
# TYPE myservice_seconds summary
myservice_seconds_count{application="micrometered",method="manual",} 4.0
myservice_seconds_sum{application="micrometered",method="manual",} 0.200378014
myservice_seconds_max{application="micrometered",method="manual",} 0.050115291
myservice_seconds_count{application="micrometered",method="supplier",} 4.0
myservice_seconds_sum{application="micrometered",method="supplier",} 0.200393455
myservice_seconds_max{application="micrometered",method="supplier",} 0.05011635
myservice_seconds_count{application="micrometered",method="sample",} 4.0
myservice_seconds_sum{application="micrometered",method="sample",} 0.200527005
myservice_seconds_max{application="micrometered",method="sample",} 0.050250191
# HELP myservice_aspect_seconds
# TYPE myservice_aspect_seconds summary
myservice_aspect_seconds_count{application="micrometered",class="io.github.mweirauch.micrometered.eval.TimingStuff$MyService",method="helloAspect",} 4.0
myservice_aspect_seconds_sum{application="micrometered",class="io.github.mweirauch.micrometered.eval.TimingStuff$MyService",method="helloAspect",} 0.201824272
myservice_aspect_seconds_max{application="micrometered",class="io.github.mweirauch.micrometered.eval.TimingStuff$MyService",method="helloAspect",} 0.051014296
回答by Michal Stepan
@io.micrometer.core.annotation.Timed
annotation seems to be out of order for custom calls due to reduction of scope, at it is mentioned in link in your question.
@io.micrometer.core.annotation.Timed
由于范围缩小,自定义调用的注释似乎不正常,在您的问题中的链接中提到。
You need to manually setup an Aspect:
您需要手动设置一个方面:
@Configuration
@EnableAspectJAutoProxy
public class AutoTimingConfiguration {
@Bean
public TimedAspect timedAspect(MeterRegistry registry) {
return new TimedAspect(registry);
}
}
This way method like this:
这种方法是这样的:
@Timed("GET_CARS")
public List<Car> getCars(){
return Lists.newArrayList();
}
will result in GET_CARS
metric in /actuator/metrics
(default) endpoint.
将导致(默认)端点中的GET_CARS
指标/actuator/metrics
。