Metrics介绍和Spring的集成
来源:互联网 发布:mysql 5.7 压力测试 编辑:程序博客网 时间:2024/05/23 16:34
http://colobu.com/2014/08/08/Metrics-and-Spring-Integration/
Metrics可以为你的代码的运行提供无与伦比的洞察力。作为一款监控指标的度量类库,它提供了很多模块可以为第三方库或者应用提供辅助统计信息, 比如Jetty, Logback, Log4j, Apache HttpClient, Ehcache, JDBI, Jersey, 它还可以将度量数据发送给Ganglia和Graphite以提供图形化的监控。
Metrics提供了Gauge、Counter、Meter、Histogram、Timer等度量工具类以及Health Check功能。
引用Metric库
将metrics-core加入到maven pom.xml中:
1234567
<dependencies><dependency><groupId>com.codahale.metrics</groupId><artifactId>metrics-core</artifactId><version>${metrics.version}</version></dependency></dependencies>
将metrics.version
设置为metrics最新的版本。
现在你可以在你的程序代码中加入一些度量了。
Registry
Metric的中心部件是MetricRegistry
。 它是程序中所有度量metric的容器。让我们接着在代码中加入一行:
final MetricRegistry metrics = new MetricRegistry();
Gauge (仪表)
Gauge
代表一个度量的即时值。 当你开汽车的时候, 当前速度是Gauge值。 你测体温的时候, 体温计的刻度是一个Gauge值。 当你的程序运行的时候, 内存使用量和CPU占用率都可以通过Gauge值来度量。
比如我们可以查看一个队列当前的size。
1234567891011121314
public class QueueManager {private final Queue queue;public QueueManager(MetricRegistry metrics, String name) {this.queue = new Queue();metrics.register(MetricRegistry.name(QueueManager.class, name, "size"),new Gauge<Integer>() {@Overridepublic Integer getValue() {return queue.size();}});}}
registry
中每一个metric
都有唯一的名字。 它可以是以.连接的字符串。 如”things.count” 和 “com.colobu.Thing.latency”。 MetricRegistry
提供了一个静态的辅助方法用来生成这个名字:
1
MetricRegistry.name(QueueManager.class, "jobs", "size")
生成的name为com.colobu.QueueManager.jobs.size
。
实际编程中对于队列或者类似队列的数据结构,你不会简单的度量
queue.size()
, 因为在Java.util和java.util.concurrent包中大部分的queue的#size是O(n),这意味的调用此方法会有性能的问题, 更深一步,可能会有lock的问题。
RatioGauge可以计算两个Gauge的比值。 Meter和Timer可以参考下面的代码创建。下面的代码用来计算计算命中率 (hit/call)。
123456789101112131415
public class CacheHitRatio extends RatioGauge {private final Meter hits;private final Timer calls;public CacheHitRatio(Meter hits, Timer calls) {this.hits = hits;this.calls = calls;}@Overridepublic Ratio getValue() {return Ratio.of(hits.oneMinuteRate(),calls.oneMinuteRate());}}
CachedGauge可以缓存耗时的测量。DerivativeGauge可以引用另外一个Gauage。
Counter (计数器)
Counter
是一个AtomicLong
实例, 可以增加或者减少值。 例如,可以用它来计数队列中加入的Job的总数。
1234567891011
private final Counter pendingJobs = metrics.counter(name(QueueManager.class, "pending-jobs"));public void addJob(Job job) {pendingJobs.inc();queue.offer(job);}public Job takeJob() {pendingJobs.dec();return queue.take();}
和上面Gauage不同,这里我们使用的是metrics.counter方法而不是metrics.register方法。 使用metrics.counter更简单。
Meter ()
Meter
用来计算事件的速率。 例如 request per second。 还可以提供1分钟,5分钟,15分钟不断更新的平均速率。
123456
private final Meter requests = metrics.meter(name(RequestHandler.class, "requests"));public void handleRequest(Request request, Response response) {requests.mark();// etc}
Histogram (直方图)
Histogram
可以为数据流提供统计数据。 除了最大值,最小值,平均值外,它还可以测量 中值(median),百分比比如XX%这样的Quantile数据 。
123456
private final Histogram responseSizes = metrics.histogram(name(RequestHandler.class, "response-sizes");public void handleRequest(Request request, Response response) {// etcresponseSizes.update(response.getContent().length);}
这个例子用来统计response的字节数。
Metrics提供了一批的Reservoir实现,非常有用。例如SlidingTimeWindowReservoir 用来统计最新N个秒(或其它时间单元)的数据。
Timer (计时器)
Timer
用来测量一段代码被调用的速率和用时。
1234567891011
private final Timer responses = metrics.timer(name(RequestHandler.class, "responses"));public String handleRequest(Request request, Response response) {final Timer.Context context = responses.time();try {// etc;return "OK";} finally {context.stop();}}
这段代码用来计算中间的代码用时以及request的速率。
Health Check (健康检查)
Metric
还提供了服务健康检查能力, 由metrics-healthchecks
模块提供。
先创建一个HealthCheckRegistry
实例。
1
final HealthCheckRegistry healthChecks = new HealthCheckRegistry();
再实现一个HealthCheck
子类, 用来检查数据库的状态。
12345678910111213141516
public class DatabaseHealthCheck extends HealthCheck {private final Database database;public DatabaseHealthCheck(Database database) {this.database = database;}@Overridepublic HealthCheck.Result check() throws Exception {if (database.isConnected()) {return HealthCheck.Result.healthy();} else {return HealthCheck.Result.unhealthy("Cannot connect to " + database.getUrl());}}}
注册一下。
1
healthChecks.register("mysql", new DatabaseHealthCheck(database));
最后运行健康检查并查看检查结果。
123456789101112
final Map<String, HealthCheck.Result> results = healthChecks.runHealthChecks();for (Entry<String, HealthCheck.Result> entry : results.entrySet()) {if (entry.getValue().isHealthy()) {System.out.println(entry.getKey() + " is healthy");} else {System.err.println(entry.getKey() + " is UNHEALTHY: " + entry.getValue().getMessage());final Throwable e = entry.getValue().getError();if (e != null) {e.printStackTrace();}}}
Metric
内置一个ThreadDeadlockHealthCheck, 它使用java内置的线程死锁检查方法来检查程序中是否有死锁。
JMX报表
通过JMX报告Metric。
12
final JmxReporter reporter = JmxReporter.forRegistry(registry).build();reporter.start();
一旦启动, 所有registry中注册的metric都可以通过JConsole或者VisualVM查看 (通过MBean插件)。
HTTP报表
Metric也提供了一个servlet (AdminServlet)提供JSON风格的报表。它还提供了单一功能的servlet (MetricsServlet, HealthCheckServlet, ThreadDumpServlet, PingServlet)。
你需要在pom.xml加入metrics-servlets。
12345
<dependency><groupId>com.codahale.metrics</groupId><artifactId>metrics-servlets</artifactId><version>${metrics.version}</version></dependency>
其它报表
除了JMX和HTTP, metric还提供其它报表。
- STDOUT, using ConsoleReporter from metrics-core
12345
final ConsoleReporter reporter = ConsoleReporter.forRegistry(registry).convertRatesTo(TimeUnit.SECONDS).convertDurationsTo(TimeUnit.MILLISECONDS).build();reporter.start(1, TimeUnit.MINUTES);
- CSV files, using CsvReporter from metrics-core
123456
final CsvReporter reporter = CsvReporter.forRegistry(registry).formatFor(Locale.US).convertRatesTo(TimeUnit.SECONDS).convertDurationsTo(TimeUnit.MILLISECONDS).build(new File("~/projects/data/"));reporter.start(1, TimeUnit.SECONDS);
- SLF4J loggers, using Slf4jReporter from metrics-core
123456
final Slf4jReporter reporter = Slf4jReporter.forRegistry(registry).outputTo(LoggerFactory.getLogger("com.example.metrics")).convertRatesTo(TimeUnit.SECONDS).convertDurationsTo(TimeUnit.MILLISECONDS).build();reporter.start(1, TimeUnit.MINUTES);
- Ganglia, using GangliaReporter from metrics-ganglia
123456
final GMetric ganglia = new GMetric("ganglia.example.com", 8649, UDPAddressingMode.MULTICAST, 1);final GangliaReporter reporter = GangliaReporter.forRegistry(registry).convertRatesTo(TimeUnit.SECONDS).convertDurationsTo(TimeUnit.MILLISECONDS).build(ganglia);reporter.start(1, TimeUnit.MINUTES);
- Graphite, using GraphiteReporter from metrics-graphite
MetricSet
可以将一组Metric组织成一组便于重用。
12345678
final Graphite graphite = new Graphite(new InetSocketAddress("graphite.example.com", 2003));final GraphiteReporter reporter = GraphiteReporter.forRegistry(registry).prefixedWith("web1.example.com").convertRatesTo(TimeUnit.SECONDS).convertDurationsTo(TimeUnit.MILLISECONDS).filter(MetricFilter.ALL).build(graphite);reporter.start(1, TimeUnit.MINUTES);
一些模块
- metrics-json提供了json格式的序列化。
以及为其它库提供度量的能力 - metrics-ehcache
- metrics-httpclient
- metrics-jdbi
- metrics-jersey
- metrics-jetty
- metrics-log4j
- metrics-logback
- metrics-jvm
- metrics-servlet 注意不是metrics-servlets
第三方库
- metrics-librato 提供Librato Metrics报表
- Metrics Spring Integration 提供了Spring的集成
- sematext-metrics-reporter 提供了SPM报表.
- wicket-metrics提供Wicket应用.
- metrics-guice 提供Guice集成.
- metrics-scala 提供了为Scala优化的API.
这里重点介绍一下Metrics for spring
Metrics for Spring
这个库为Spring增加了Metric库, 提供基于XML或者注解方式。
- 可以使用注解创建metric和代理类。 @Timed, @Metered, @ExceptionMetered, @Counted
- 为注解了 @Gauge 和 @CachedGauge的bean注册Gauge
- 为@Metric注解的字段自动装配
- 注册HealthCheck
- 通过XML配置产生报表
- 通过XML注册metric和metric组
你需要在pom.xml加入
12345
<dependency><groupId>com.ryantenney.metrics</groupId><artifactId>metrics-spring</artifactId><version>3.0.1</version></dependency>
基本用法
- XML风格的配置
1234567891011121314151617181920212223242526272829
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:metrics="http://www.ryantenney.com/schema/metrics"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.2.xsdhttp://www.ryantenney.com/schema/metricshttp://www.ryantenney.com/schema/metrics/metrics-3.0.xsd"><!-- Registry should be defined in only one context XML file --><metrics:metric-registry id="metrics" /><!-- annotation-driven must be included in all context files --><metrics:annotation-driven metric-registry="metrics" /><!-- (Optional) Registry should be defined in only one context XML file --><metrics:reporter type="console" metric-registry="metrics" period="1m" /><!-- (Optional) The metrics in this example require the metrics-jvm jar--><metrics:register metric-registry="metrics"><bean metrics:name="jvm.gc" class="com.codahale.metrics.jvm.GarbageCollectorMetricSet" /><bean metrics:name="jvm.memory" class="com.codahale.metrics.jvm.MemoryUsageGaugeSet" /><bean metrics:name="jvm.thread-states" class="com.codahale.metrics.jvm.ThreadStatesGaugeSet" /><bean metrics:name="jvm.fd.usage" class="com.codahale.metrics.jvm.FileDescriptorRatioGauge" /></metrics:register><!-- Beans and other Spring config --></beans>
- java注解的方式
123456789101112131415161718192021
import java.util.concurrent.TimeUnit;import org.springframework.context.annotation.Configuration;import com.codahale.metrics.ConsoleReporter;import com.codahale.metrics.MetricRegistry;import com.codahale.metrics.SharedMetricRegistries;import com.ryantenney.metrics.spring.config.annotation.EnableMetrics;import com.ryantenney.metrics.spring.config.annotation.MetricsConfigurerAdapter;@Configuration@EnableMetricspublic class SpringConfiguringClass extends MetricsConfigurerAdapter {@Overridepublic void configureReporters(MetricRegistry metricRegistry) {ConsoleReporter.forRegistry(metricRegistry).build().start(1, TimeUnit.MINUTES);}}
更多的信息请参照这里
- Metrics介绍和Spring的集成
- Metrics介绍和Spring的集成
- Metrics介绍和Spring的集成
- 将osworkflow与spring和hibernate集成的基本介绍
- Metrics介绍
- Metrics介绍
- 关于java的Metrics的简单介绍
- spring 集成memcached的详细介绍
- Spring集成memcached的详细介绍
- CXF与Spring的集成图文介绍
- drools和spring的集成
- spring和struts的集成
- spring和struts的集成
- Spring 和 Hibernate的集成
- JSF和Spring的集成
- JSF和Spring的集成
- spring和quartz的集成
- Spring 和 Hibernate的集成
- 4.React中文之组件和属性
- Spring 任务调度
- “移动互联网+”时代正在到来
- 关于分布式事务、两阶段提交、一阶段提交、Best Efforts 1PC模式和事务补偿机制的研究
- Oracle 数据库异机升级
- Metrics介绍和Spring的集成
- BeanUtils封装日期类空指针错误
- cmake 测试
- Mysql学习历程(10)-关系
- linux以用户分组的方式做文件权限管理实例
- 5.React中文之状态和生命周期
- 解决WebViewActivity 退出后还在播放音视频的问题
- Android——内存篇:Android中5种最常见的内存泄漏问题以及解决办法
- SQL SERVER的DATALENGTH()函数和LEN()函数