Spring Boot 默認指標從哪來?

瞭解有關 Spring Boot 默認指標及其來源的更多信息。html

您是否注意到 Spring Boot 和 Micrometer 爲您的應用生成的全部默認指標? 若是沒有 - 您能夠將 actuator 依賴項添加到項目中,而後點擊 / actuator / metrics 端點,在那裏您將找到有關 JVM 、進程、Tomcat、流量等的有用信息。 而後,添加一些緩存數據源 或 JPA 依賴項,甚至會出現更多指標。若是您想知道它們是如何結束的,咱們能夠在哪裏找到關於它們所描述的參數的解釋,那麼這篇文章就是爲您準備的。java

顯示指標

爲了讓它井井有理,讓咱們從如何在 Spring Boot 應用程序中顯示指標開始。若是您已經知道了,能夠跳過這一部分。git

Spring Boot中的指標由 micrometer.io 處理。可是,若是您使用 actuator ,則不須要向項目添加 micrometer 依賴項,由於 actuator 已經依賴於它。即便您對它提供的端點不感興趣,也但願您使用 actuator ,由於這是經過其 AutoConfigurations 註冊許多指標的模塊。稍後咱們會詳細討論。github

所以,首先,只需將執行器依賴項添加到項目中(這裏是 build.gradle.kts )web

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-actuator")
}複製代碼

並在執行器端點中顯示指標名稱,點擊 http://localhost:8080/actuator/metrics.spring

{
  "names": [
    "jvm.threads.states",
    "process.files.max",
    "jvm.memory.used",
    "jvm.gc.memory.promoted",
    "jvm.memory.max",
    "system.load.average.1m",
    ...
  ]
}複製代碼

而後,要查看詳細信息,請在 URL 路徑中添加指標名稱,例如: http://localhost:8080/actuator/metrics/system.cpu.count.緩存

{
  "name": "system.cpu.count",
  "description": "The number of processors available to the Java virtual machine",
  "baseUnit": null,
  "measurements": [
    {
      "statistic": "VALUE",
      "value": 8
    }
  ],
  "availableTags": [
  ]
}複製代碼

經過提供特定的儀表註冊表,能夠按期將這些指標發送到您選擇的指標系統( PrometheusNew RelicCloudWatchGraphite 等)。 讓咱們用最簡單的註冊表來作 - LoggingMeterRegistry,它只是按期記錄全部指標。tomcat

@Configuration
class MetricsConfig {
    @Bean
    LoggingMeterRegistry loggingMeterRegistry() {
        return new LoggingMeterRegistry();
    }
}複製代碼

如今,指標也顯示在日誌中:session

2019-07-17 11:07:09.406  INFO 91283 --- [trics-publisher] i.m.c.i.logging.LoggingMeterRegistry     : jvm.buffer.count{id=direct} value=0 buffers
2019-07-17 11:07:09.406  INFO 91283 --- [trics-publisher] i.m.c.i.logging.LoggingMeterRegistry     : jvm.buffer.count{id=mapped} value=0 buffers
2019-07-17 11:07:09.406  INFO 91283 --- [trics-publisher] i.m.c.i.logging.LoggingMeterRegistry     : jvm.buffer.memory.used{id=direct} value=0 B
2019-07-17 11:07:09.406  INFO 91283 --- [trics-publisher] i.m.c.i.logging.LoggingMeterRegistry     : jvm.buffer.memory.used{id=mapped} value=0 B
2019-07-17 11:07:09.408  INFO 91283 --- [trics-publisher] i.m.c.i.logging.LoggingMeterRegistry     : jvm.classes.loaded{} value=8530 classes
2019-07-17 11:07:09.408  INFO 91283 --- [trics-publisher] i.m.c.i.logging.LoggingMeterRegistry     : jvm.gc.live.data.size{} value=0 B
2019-07-17 11:07:09.408  INFO 91283 --- [trics-publisher] i.m.c.i.logging.LoggingMeterRegistry     : jvm.gc.max.data.size{} value=0 B
2019-07-17 11:07:09.410  INFO 91283 --- [trics-publisher] i.m.c.i.logging.LoggingMeterRegistry     : jvm.memory.committed{area=nonheap,id=Compressed Class Space} value=6.25 MiB
2019-07-17 11:07:09.410  INFO 91283 --- [trics-publisher] i.m.c.i.logging.LoggingMeterRegistry     : jvm.memory.committed{area=heap,id=G1 Eden Space} value=168 MiB
...複製代碼

指標供應

那麼,如何提供這些指標呢?一個示例多是 WebMvcMetricsFilter ,向全部 Spring Web MVC 端點添加性能指標 (http.server.requests metric)架構

可是這個例子很簡單。當全部請求都由 Spring 框架處理時,在內部添加調用生成指標是沒有必要的(只檢查 WebMvcMetricsFilter.record() 方法)。

可是,若是您使用純 ehcachehibernate 或其餘數據源,而後生成指標,狀況又會如何呢?

那麼 cache. * 指標呢,即便我 `@Autowired` 純 `net.sf.ehcache.Cache` 也會生成?

那麼 hibernate. * 指標呢,即便我 `@Autowired` 純 `org.hibernate.SessionFactory` 也會生成?

而後, jvm.*process.*tomcat.* 等如何自動生成?

它彷佛比人們想象的更簡單,由於這些統計數據是由受監控的組件自己提供的。 有時,它將直接提供,例如cache.getStatistics()EhCache 提供 StatisticsGateway sessionFactory.getStatistics()Hibernate SessionFactory 提供 statistics 等等。

有時,這能夠經過其餘方式實現,好比託管 bean 。例如,將 RuntimeMXBean 用於 JVM process.* 指標以及 將(如GlobalRequestProcessorServlet 等) Tomcat mbeans 用於 tomcat. * 指標

爲了訪問這些統計數據並將其轉換爲特定指標,Micrometer 引入了 MeterBinder 的概念。

檢查 MeterBinder implementation 層次結構,您將瞭解更多關於可用的指標組的信息。

Micrometer MeterBinders

您也能夠直接在 micrometer repo 上檢查。

打開,例如, EhCache2Metrics ,您將找到 Ehcache 統計信息映射到特定 Micrometer 指標的內容和方式。

cache.size -> StatisticsGateway:getSize cache.gets{result=miss} -> StatisticsGateway:cacheMissCount cache.gets{result=hit} -> StatisticsGateway:cacheHitCount cache.puts -> StatisticsGateway:cachePutCount cache.evictions -> StatisticsGateway:cacheEvictedCount cache.remoteSize -> StatisticsGateway::getRemoteSize cache.removals -> StatisticsGateway::cacheRemoveCount cache.puts.added{result=added} -> StatisticsGateway::cachePutAddedCount cache.puts.added{result=updated} -> StatisticsGateway::cachePutAddedCount cache.misses{reason=expired} -> StatisticsGateway::cacheMissExpiredCount) cache.misses{reason=notFound} -> StatisticsGateway::cacheMissNotFoundCount) cache.xa.commits{result=readOnly} -> StatisticsGateway::xaCommitReadOnlyCount cache.xa.commits{result=exception} -> StatisticsGateway::xaCommitExceptionCount cache.xa.commits{result=committed} -> StatisticsGateway::xaCommitCommittedCount cache.xa.rollbacks{result=exception} -> StatisticsGateway::xaRollbackExceptionCount cache.xa.rollbacks{result=success} -> StatisticsGateway::xaRollbackSuccessCount cache.xa.recoveries{result=nothing} -> StatisticsGateway::xaRecoveryNothingCount cache.xa.recoveries{result=success} -> StatisticsGateway::xaRecoveryRecoveredCount cache.local.offheap.size -> StatisticsGateway::getLocalOffHeapSize) cache.local.heap.size -> StatisticsGateway::getLocalHeapSizeInBytes cache.local.disk.size -> StatisticsGateway::getLocalDiskSizeInBytes複製代碼

註冊 MeterBinders 是很是簡單的,示例能夠在 micrometer 文檔 中被找到。

記住,您能夠手動操做:

new ClassLoaderMetrics().bindTo(registry);
new JvmMemoryMetrics().bindTo(registry);
new EhCache2Metrics(cache, Tags.of("name", cache.getName())).bindTo(registry)
new TomcatMetrics(manager, tags).bindTo(registry)
...複製代碼

或者,您可使用 Spring Boot ,它會在引擎下爲您作這件事。

正如我以前提到的,actuator 將提供許多 AutoConfiguration s 和 MetricsBinders ,只要添加給定的依賴項,它就會註冊 MeterBinders

例如, TomcatMetricsBinder 將註冊 TomcatMetrics (爲您的嵌入式容器)。MeterRegistryConfigurer 將註冊 JVM 、運行時間 和其餘系統指標。

如今,假設您想在您的應用程序中使用 Ehcache 。 您能夠添加兩個依賴項:

implementation("org.springframework.boot:spring-boot-starter-cache")
    implementation("net.sf.ehcache:ehcache")複製代碼

而後註冊緩存(您也能夠經過 ehcache.xml 來實現)

@Bean
    Cache playCache(EhCacheCacheManager cacheManager) {
        CacheConfiguration cacheConfiguration = new CacheConfiguration()
            .name(CACHE_NAME)
            .maxEntriesLocalHeap(MAX_ELEMENTS_IN_MEMORY);
        Cache cache = new Cache(cacheConfiguration);
        cacheManager.getCacheManager().addCache(cache);
        cacheManager.initializeCaches();
        return cache;
    }複製代碼

如今, CacheMetricsRegistrarConfiguration 將經過 Spring 緩存管理器爲每個緩存管理註冊 EhCache2Metrics

若是您不想使用 Spring 緩存管理,您也能夠本身註冊 EhCache2Metrics

如今,啓動應用程序,您將看到其餘 ehcache 指標。

2019-07-17 13:08:45.113  INFO 93052 --- [trics-publisher] i.m.c.i.logging.LoggingMeterRegistry     : cache.gets{cache=playCache,cacheManager=cacheManager,name=playCache,result=hit} throughput=12.95/s
2019-07-17 13:08:45.124  INFO 93052 --- [       Thread-4] i.m.c.i.logging.LoggingMeterRegistry     : cache.misses{cache=playCache,cacheManager=cacheManager,name=playCache,reason=notFound} throughput=3.7/s
2019-07-17 13:08:45.124  INFO 93052 --- [trics-publisher] i.m.c.i.logging.LoggingMeterRegistry     : cache.gets{cache=playCache,cacheManager=cacheManager,name=playCache,result=miss} throughput=3.7/s
2019-07-17 13:08:48.840  INFO 93052 --- [       Thread-4] i.m.c.i.logging.LoggingMeterRegistry     : cache.puts{cache=playCache,cacheManager=cacheManager,name=playCache} throughput=16.65/s
2019-07-17 13:08:48.840  INFO 93052 --- [trics-publisher] i.m.c.i.logging.LoggingMeterRegistry     : cache.misses{cache=playCache,cacheManager=cacheManager,name=playCache,reason=notFound} throughput=3.7/s
2019-07-17 13:08:48.841  INFO 93052 --- [trics-publisher] i.m.c.i.logging.LoggingMeterRegistry     : cache.puts{cache=playCache,cacheManager=cacheManager,name=playCache} throughput=16.65/s
2019-07-17 13:08:48.841  INFO 93052 --- [       Thread-4] i.m.c.i.logging.LoggingMeterRegistry     : cache.puts.added{cache=playCache,cacheManager=cacheManager,name=playCache,result=updated} throughput=0.116667/s
2019-07-17 13:08:48.841  INFO 93052 --- [trics-publisher] i.m.c.i.logging.LoggingMeterRegistry     : cache.puts.added{cache=playCache,cacheManager=cacheManager,name=playCache,result=updated} throughput=0.116667/s
2019-07-17 13:08:48.841  INFO 93052 --- [       Thread-4] i.m.c.i.logging.LoggingMeterRegistry     : cache.puts.added{cache=playCache,cacheManager=cacheManager,name=playCache,result=added} throughput=0.116667/s
2019-07-17 13:08:48.842  INFO 93052 --- [trics-publisher] i.m.c.i.logging.LoggingMeterRegistry     : cache.puts.added{cache=playCache,cacheManager=cacheManager,name=playCache,result=added} throughput=0.116667/s
2019-07-17 13:08:48.847  INFO 93052 --- [trics-publisher] i.m.c.i.logging.LoggingMeterRegistry     : cache.local.disk.size{cache=playCache,cacheManager=cacheManager,name=playCache} value=0 B
2019-07-17 13:08:48.847  INFO 93052 --- [       Thread-4] i.m.c.i.logging.LoggingMeterRegistry     : cache.local.disk.size{cache=playCache,cacheManager=cacheManager,name=playCache} value=0 B
2019-07-17 13:08:48.908  INFO 93052 --- [       Thread-4] i.m.c.i.logging.LoggingMeterRegistry     : cache.local.heap.size{cache=playCache,cacheManager=cacheManager,name=playCache} value=1.039062 KiB
2019-07-17 13:08:48.908  INFO 93052 --- [trics-publisher] i.m.c.i.logging.LoggingMeterRegistry     : cache.local.heap.size{cache=playCache,cacheManager=cacheManager,name=playCache} value=1.039062 KiB
2019-07-17 13:08:48.909  INFO 93052 --- [trics-publisher] i.m.c.i.logging.LoggingMeterRegistry     : cache.local.offheap.size{cache=playCache,cacheManager=cacheManager,name=playCache} value=0 B
2019-07-17 13:08:48.909  INFO 93052 --- [       Thread-4] i.m.c.i.logging.LoggingMeterRegistry     : cache.local.offheap.size{cache=playCache,cacheManager=cacheManager,name=playCache} value=0 B
2019-07-17 13:08:48.909  INFO 93052 --- [       Thread-4] i.m.c.i.logging.LoggingMeterRegistry     : cache.remoteSize{} value=0
2019-07-17 13:08:48.909  INFO 93052 --- [trics-publisher] i.m.c.i.logging.LoggingMeterRegistry     : cache.remoteSize{} value=0
2019-07-17 13:08:48.909  INFO 93052 --- [       Thread-4] i.m.c.i.logging.LoggingMeterRegistry     : cache.size{cache=playCache,cacheManager=cacheManager,name=playCache} value=7
2019-07-17 13:08:48.909  INFO 93052 --- [trics-publisher] i.m.c.i.logging.LoggingMeterRegistry     : cache.size{cache=playCache,cacheManager=cacheManager,name=playCache} value=7複製代碼

在這種狀況下,指標上下文中每一個組件的職責可概括爲:

Ehcache 指標架構

您能夠在 此處 提供的示例應用中查看全部這些概念。

編碼快樂!

原文:https://dzone.com/articles/spring-boot-where-do-the-default-metrics-come-from

做者:Dawid Kublik

譯者:Queena
------

8月福利準時來襲,關注公衆號​後臺回覆:003便可領取7月翻譯集錦哦~​往期福利回覆:001,002便可領取!

img

相關文章
相關標籤/搜索