1.背景
prometheus是一個以神名為名的工具,有"先知先覺"的寓意。prometheus是一套開源的系統監控報警框架,十分符合它的定位。它啟發於 Google 的 borgmon 監控系統,由工作在 SoundCloud 的 google 前員工在 2012 年創建,作為社區開源項目進行開發,並於 2015 年正式發布。prometheus,不是一個單一工具,它是由多個組件組合起來的工具。對剛剛開始學習的同學可以先看一下這邊文章,讓大家對prometheus有一個基本了解: https://www.cnblogs.com/linuxk/p/12017580.html(非常推薦)
2.基礎架構
Prometheus 由多個組件組成,但是其中許多組件是可選的:
服務端:
- Prometheus Server:服務段組件,它是 Prometheus 核心組件,用於收集指標和存儲時間序列數據,並提供查詢接口。
- push gateway:網關組件,可以將它視為一個特殊 node_exporter 組件。主要用於臨時性的 jobs。由於這類 jobs 存在時間較短,可能在 Prometheus 來 pull 之前就消失了。對此Jobs定時將指標push到pushgateway,再由Prometheus Server從Pushgateway上pull,根據業務需要可配置。
客戶端:
- node_exporter:客戶端收集器組件,用於暴露已有的第三方服務的 metrics(指標) 給 Prometheus。
- alertmanager:監控告警組件,從 Prometheus server 端接收到 alerts 后,會進行去除重復數據,分組,並路由到對收的接受方式,發出報警。常見的接收方式有:電子郵件,pagerduty,OpsGenie, webhook 等,根據業務需要可配置。
- Web UI:視圖組件,Prometheus內置一個簡單的Web控制台,可以查詢指標,查看配置信息或者Service Discovery等,實際工作中,查看指標或者創建儀表盤通常使用Grafana,Prometheus作為Grafana的數據源,根據業務需要可配置。
- client Library:客戶端服務(例如Go,Python,Java等),為需要監控的服務產生相應的/metrics並暴露給Prometheus Server。目前已經有很多的軟件原生就支持Prometheus,提供/metrics,可以直接使用。對於像操作系統已經不提供/metrics,可以使用exporter,或者自己開發exporter來提供/metrics服務,根據業務需要可配置。
3.Prometheus獲取指標方式
prometheus客戶端主要由2種數據采集的方式:
pull(拉取形式):指的是客戶端(被監控主機)先安裝各類已有的exporters在系統上,exporters以守護進程的模式運行,並開始采集數據,exporters本身也是一個http_server,可以對http請求作出響應,並返回K/V數據,也就是metrics。prometheus通過用pull的方式(HTTP_GET)去訪問每個節點上的exporter並采集回需要的數據。
push(推送的形式):指的是客戶端(或服務端)安裝官方的pushgateway插件,然后通過我們自行編寫的各種腳本,將監控數據組織成K/V的形式(metrics形式)發送給pushgateway,而后pushgateway再推送給prometheus,這里需要注意的是pushgateway不一定要安裝在被監控端,也可以安裝在服務端,甚至是一台不相關的主機上,換句話來說,它只是一個中間轉發的媒介。
4.執行流程
short_lived: 就是本地自定義腳本,它會定時將指標信息推送到pushgateway。感覺pushgateway就是一個特殊的node_exporter。具體使用方式:http://www.linuxe.cn/post-506.html
5.metrics指標類型
Counter: counter 是一個累積計數的指標,僅支持增加或者重置為0(只增不減 )。例如:可以用來統計服務請求的數量,任務完成數量,或者出錯的數量。
Gauge: gauge是一個純數值型的能夠經常進行增加或者減少的指標。例如用來做溫度的計數,內存的使用,同樣也可以用來使用計算服務請求數量。
Histogram:直方圖,histogram 在一段時間內進行采樣,並能夠對指定區間以及總數進行統計.
Summary: summary與histogram類似,用於表示一段時間內的采樣數據,但它直接存儲了分位數,而不是通過區間來計算。
6.埋點
spring-actuator做度量統計收集,使用Prometheus(普羅米修斯)進行數據收集,Grafana(增強ui)進行數據展示,用於監控生成環境機器的性能指標和業務數據指標。一般,我們叫這樣的操作為”埋點”。SpringBoot中的依賴spring-actuator中集成的度量統計API使用的框架是Micrometer,官網是Micrometer.io。
1. 引入Prometheus metrics 包
<!-- https://mvnrepository.com/artifact/io.micrometer/micrometer-core -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
<version>1.6.6</version>
</dependency>
2. 以使用http client 為例。
import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; import io.micrometer.core.instrument.Counter; import io.micrometer.core.instrument.DistributionSummary; import io.micrometer.core.instrument.Gauge; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Timer; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; /** * * @date 2021-04-29 2:59 下午 */ public class Test3 { private static final MeterRegistry registry = new SimpleMeterRegistry(); public static void main(String[] args) { String[] tags = formattedTag(builderTag()); //折線圖 new Test3().counter("HTTP_SUCCESS_COUNT","http請求成功次數",tags); //折線圖 new Test3().timer("RT",10000L,"http請求響應時間",tags); //樹狀圖 GaugeDemo gaugeDemo = new GaugeDemo(); gaugeDemo.setGaugeMetricsName("xxxx"); gaugeDemo.setMetrics(1); new Test3().gauge("Memory_metrics_test",gaugeDemo,"內存變化指標",tags); // 響應成功占比 : 餅狀圖 new Test3().summary("summary_http_success",0.98d,"響應成功占比",100,tags); } /** * 使用者也可以自行繼承MeterRegistry去實現自定義的MeterRegistry。SimpleMeterRegistry適合做調試的時候使用,它的簡單使用方式如下 * @param name 指標key * @param desc 基礎單位 * @param tags 標簽信息 * 折線圖 */ private void counter(String name,String desc,String... tags){ Counter counter = Counter.builder(name) .description(desc) //標簽 .tags(tags) //綁定的MeterRegistry .register(registry); //數值加一,原子操作 counter.increment(); } /** * 時間埋點 * @param name 指標key * @param nanoSeconds 響應時間 * @param desc 描述 * @param tags 標簽信息 * 折線圖 */ private void timer(String name,Long nanoSeconds,String desc,String... tags){ Timer timer = Timer.builder(name) .description(desc) //標簽 .tags(tags) //綁定的MeterRegistry .register(registry); //數值加一,原子操作 timer.record(nanoSeconds, TimeUnit.NANOSECONDS); } /** * 數值埋點是個 Gauge, 可以用在查看某個場景單位時間內的變化的情形。 * 樹狀圖 * @param name 指標key * @param gaugeDemo 指標對象 * @param desc 指標描述信息 * @param tags 標簽信息 */ private void gauge(String name,GaugeDemo gaugeDemo,String desc,String... tags){ Gauge gauge = Gauge.builder(name,gaugeDemo,GaugeDemo::getMetrics) .description(desc) //標簽 .tags(tags) //綁定的MeterRegistry .register(registry); } /** * Summary(摘要)主要用於跟蹤事件的分布,在Micrometer中,對應的類是DistributionSummary(分發摘要)。它的使用方式和Timer十分相似,但是它的記錄值並不依賴於時間單位。 * 餅狀圖 * 例如: 某個指標的百分比 * @param name 指標key * @param desc 描述信息 * @param scale 將記錄到分布摘要的值乘以比例因子。 可配置 * @param tags 標簽信息 * @param value 計算值 */ private void summary(String name,double value,String desc ,double scale,String... tags ){ DistributionSummary summary = DistributionSummary .builder(name) .description(desc) .tags(tags) .scale(scale) .register(registry); summary.record(value); } private static class GaugeDemo{ /** * 指標名 */ private String gaugeMetricsName; /** * 度量指標 */ private Integer metrics; public String getGaugeMetricsName() { return gaugeMetricsName; } public void setGaugeMetricsName(String gaugeMetricsName) { this.gaugeMetricsName = gaugeMetricsName; } public Integer getMetrics() { return metrics; } public void setMetrics(Integer metrics) { this.metrics = metrics; } } private static String[] formattedTag(Map<String,String> tag){ String[] result = new String[tag.size() * 2]; int i = 0; for (Map.Entry<String, String> entry : tag.entrySet()){ result[i] = entry.getKey(); i++; result[i] = entry.getValue(); i++; } return result; } private static Map<String,String> builderTag(){ /** * 1、Tag的值必須不為null。 * * 2、Micrometer中,Tag必須成對出現,也就是Tag必須設置為偶數個,實際上它們以Key=Value的形式存在 */ HashMap<String, String> tags = new HashMap<>(); tags.put("url","wwww.baidu.com"); tags.put("code","200"); tags.put("method","POST"); return tags; } }
當然,還有其他類型,有其他擴展類型。就不一一舉例了。
效果顯示
我們的項目是基於spring cloud組件來處理的,我們可以通過訪問這個地址就可以看到我們上報給prometheus的信息
http://服務ip:服務端口/actuator/prometheus
將會得到如下信息:
-- 描述信息: 請求響應時間 指標
# HELP fusion_http_response_time_seconds response.time
-- 統計的類型 # TYPE fusion_http_response_time_seconds summary
-- 指標key: RT ,{} 這個括號中的就是你寫入的 tag 信息, 最后面一個是指標
RT{bizCode="0",endpoint="[GET]/actuator/health",method="GET",mode="servlet",status="200",type="",} 58331.0
7.Prometheus本地存儲
TSDB
Prometheus本地儲存使用它自己寫的TSDB(時序數據庫)
時序數據庫全稱為時間序列數據庫。時間序列數據庫主要用於指處理帶時間標簽(按照時間的順序變化,即時間序列化)的數據,帶時間標簽的數據也稱為時間序列數據。主要用於存儲周期性的采集各種實時監控信息。
目錄結構
./data ├── 01BKGV7JBM69T2G1BGBGM6KB12 │ └── meta.json ├── 01BKGTZQ1SYQJTR4PB43C8PD98 │ ├── chunks │ │ └── 000001 │ ├── tombstones │ ├── index │ └── meta.json ├── 01BKGTZQ1HHWHV8FBJXW1Y3W0K │ └── meta.json ├── 01BKGV7JC0RY8A6MACW02A2PJD │ ├── chunks │ │ └── 000001 │ ├── tombstones │ ├── index │ └── meta.json └── wal ├── 00000002 └── checkpoint.00000
儲存原理(write)
8.其他監控工具對比
引用
https://www.sohu.com/a/342733264_198222
https://www.cnblogs.com/linuxk/p/12017580.html
http://www.linuxe.cn/post-506.html
https://www.freesion.com/article/5362527244/
https://www.jianshu.com/p/a80cc630fa73