詳解Metrics應(yīng)用監(jiān)控指標的使用說明
題前:做過虛擬化級別、系統(tǒng)級別、容器級別監(jiān)控;應(yīng)用級別監(jiān)控有哪些方法可以做?
Metrics是個很好的選擇。java、python、go均可支持。
Metrics可以為你的代碼的運行提供無與倫比的洞察力。作為一款監(jiān)控指標的度量類庫,它提供了很多模塊可以為第三方庫或者應(yīng)用提供輔助統(tǒng)計信息, 比如Jetty, Logback, Log4j, Apache HttpClient, Ehcache, JDBI, Jersey, 它還可以將度量數(shù)據(jù)發(fā)送給Ganglia和Graphite以提供圖形化的監(jiān)控。
Metrics提供了Gauge、Counter、Meter、Histogram、Timer等度量工具類以及Health Check功能。
引用Metric庫
將metrics-core加入到maven pom.xml中:
<dependencies> <dependency> <groupId>com.codahale.metrics</groupId> <artifactId>metrics-core</artifactId> <version>${metrics.version}</version> </dependency> </dependencies>
將metrics.version
設(shè)置為metrics最新的版本。
現(xiàn)在你可以在你的程序代碼中加入一些度量了。
Registry
Metric的中心部件是MetricRegistry
。 它是程序中所有度量metric的容器。讓我們接著在代碼中加入一行:
final MetricRegistry metrics = new MetricRegistry();
Gauge (儀表)
Gauge
代表一個度量的即時值。 當(dāng)你開汽車的時候, 當(dāng)前速度是Gauge值。 你測體溫的時候, 體溫計的刻度是一個Gauge值。 當(dāng)你的程序運行的時候, 內(nèi)存使用量和CPU占用率都可以通過Gauge值來度量。
比如我們可以查看一個隊列當(dāng)前的size。
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>() { @Override public Integer getValue() { return queue.size(); } } ); } }
registry
中每一個metric
都有唯一的名字。 它可以是以.連接的字符串。 如"things.count" 和 "com.colobu.Thing.latency"。 MetricRegistry
提供了一個靜態(tài)的輔助方法用來生成這個名字:
MetricRegistry.name(QueueManager.class, "jobs", "size")
生成的name為com.colobu.QueueManager.jobs.size
。
實際編程中對于隊列或者類似隊列的數(shù)據(jù)結(jié)構(gòu),你不會簡單的度量queue.size(), 因為在java.util和java.util.concurrent包中大部分的queue的#size是O(n),這意味的調(diào)用此方法會有性能的問題, 更深一步,可能會有l(wèi)ock的問題。
RatioGauge可以計算兩個Gauge的比值。 Meter和Timer可以參考下面的代碼創(chuàng)建。下面的代碼用來計算計算命中率 (hit/call)。
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; } @Override public Ratio getValue() { return Ratio.of(hits.oneMinuteRate(), calls.oneMinuteRate()); } }
CachedGauge可以緩存耗時的測量。DerivativeGauge可以引用另外一個Gauage。
Counter (計數(shù)器)
Counter
是一個AtomicLong
實例, 可以增加或者減少值。 例如,可以用它來計數(shù)隊列中加入的Job的總數(shù)。
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分鐘不斷更新的平均速率。
private final Histogram responseSizes = metrics.histogram(name(RequestHandler.class, "response-sizes"); public void handleRequest(Request request, Response response) { // etc responseSizes.update(response.getContent().length); }
Histogram (直方圖)
Histogram
可以為數(shù)據(jù)流提供統(tǒng)計數(shù)據(jù)。 除了最大值,最小值,平均值外,它還可以測量 中值(median),百分比比如XX%這樣的Quantile數(shù)據(jù) 。
private final Histogram responseSizes = metrics.histogram(name(RequestHandler.class, "response-sizes"); public void handleRequest(Request request, Response response) { // etc responseSizes.update(response.getContent().length); }
這個例子用來統(tǒng)計response的字節(jié)數(shù)。
Metrics提供了一批的Reservoir實現(xiàn),非常有用。例如SlidingTimeWindowReservoir 用來統(tǒng)計最新N個秒(或其它時間單元)的數(shù)據(jù)。
Timer (計時器)
Timer
用來測量一段代碼被調(diào)用的速率和用時。
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
還提供了服務(wù)健康檢查能力, 由metrics-healthchecks
模塊提供。
先創(chuàng)建一個HealthCheckRegistry
實例。
final HealthCheckRegistry healthChecks = new HealthCheckRegistry();
再實現(xiàn)一個HealthCheck
子類, 用來檢查數(shù)據(jù)庫的狀態(tài)。
public class DatabaseHealthCheck extends HealthCheck { private final Database database; public DatabaseHealthCheck(Database database) { this.database = database; } @Override public HealthCheck.Result check() throws Exception { if (database.isConnected()) { return HealthCheck.Result.healthy(); } else { return HealthCheck.Result.unhealthy("Cannot connect to " + database.getUrl()); } } }
注冊一下。
healthChecks.register("mysql", new DatabaseHealthCheck(database));
最后運行健康檢查并查看檢查結(jié)果。
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
內(nèi)置一個ThreadDeadlockHealthCheck, 它使用java內(nèi)置的線程死鎖檢查方法來檢查程序中是否有死鎖。
JMX報表
通過JMX報告Metric。
final JmxReporter reporter = JmxReporter.forRegistry(registry).build(); reporter.start();
一旦啟動, 所有registry中注冊的metric都可以通過JConsole或者VisualVM查看 (通過MBean插件)。
HTTP報表
Metric也提供了一個servlet (AdminServlet)提供JSON風(fēng)格的報表。它還提供了單一功能的servlet (MetricsServlet, HealthCheckServlet, ThreadDumpServlet, PingServlet)。
你需要在pom.xml加入metrics-servlets。
<dependency> <groupId>com.codahale.metrics</groupId> <artifactId>metrics-servlets</artifactId> <version>${metrics.version}</version> </dependency>
其它報表
除了JMX和HTTP, metric還提供其它報表。
STDOUT, using ConsoleReporter from metrics-core
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
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
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
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組織成一組便于重用。
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-ehcachemetrics-httpclientmetrics-jdbimetrics-jerseymetrics-jettymetrics-log4jmetrics-logbackmetrics-jvmmetrics-servlet 注意不是metrics-servlets
第三方庫
- metrics-librato 提供Librato Metrics報表
- Metrics Spring Integration 提供了Spring的集成
- sematext-metrics-reporter 提供了SPM報表.
- wicket-metrics提供Wicket應(yīng)用.
- metrics-guice 提供Guice集成.
- metrics-scala 提供了為Scala優(yōu)化的API.
這里重點介紹一下Metrics for Spring
Metrics for Spring
這個庫為Spring增加了Metric庫, 提供基于XML或者注解方式。
- 可以使用注解創(chuàng)建metric和代理類。 @Timed, @Metered, @ExceptionMetered, @Counted
- 為注解了 @Gauge 和 @CachedGauge的bean注冊Gauge
- 為@Metric注解的字段自動裝配
- 注冊HealthCheck
- 通過XML配置產(chǎn)生報表
- 通過XML注冊metric和metric組
你需要在pom.xml加入
<dependency> <groupId>com.ryantenney.metrics</groupId> <artifactId>metrics-spring</artifactId> <version>3.0.1</version> </dependency>
基本用法
XML風(fēng)格的配置
<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/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.ryantenney.com/schema/metrics http://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注解的方式
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 @EnableMetrics public class SpringConfiguringClass extends MetricsConfigurerAdapter { @Override public void configureReporters(MetricRegistry metricRegistry) { ConsoleReporter.forRegistry(metricRegistry).build().start(1, TimeUnit.MINUTES); } }
注: go Metrics使用: Go語言metrics應(yīng)用監(jiān)控指標基本使用說明
以上就是詳解Metrics應(yīng)用監(jiān)控指標的使用說明的詳細內(nèi)容,更多關(guān)于Metrics應(yīng)用監(jiān)控指標使用的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
VSCode 使用Settings Sync同步配置(最新版教程,非常簡單)
這篇文章主要介紹了VSCode 使用Settings Sync同步配置(最新版教程,非常簡單),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11使用HTTP_X_FORWARDED_FOR獲取客戶端IP的嚴重后果
我的建議是不要再使用上面的方法去獲取客戶端IP.即是不要再理會代理情況.2009-11-11VSCode讓終端默認在當(dāng)前文件的路徑啟動(方法推薦)
這篇文章主要介紹了VSCode中如何讓終端默認在當(dāng)前文件的路徑啟動,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-03-03Jenkins定時構(gòu)建語法規(guī)則及時間設(shè)置
這篇文章主要為大家介紹了Jenkins定時構(gòu)建時間設(shè)置,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-06-06