業(yè)務系統(tǒng)的Prometheus實踐示例詳解
什么是 Prometheus
Prometheus(普羅米修斯)是古希臘的一個神明,名字的意思是「先見之明」。從它的名字可以看出,Prometheus 是做「先見之明」的監(jiān)控告警用途。
官網(wǎng)描述為From metrics to insight
,用指標洞察系統(tǒng)。
Prometheus 其實就是一個數(shù)據(jù)監(jiān)控解決方案,它能幫你簡單快速地搭建起一套可視化的監(jiān)控系統(tǒng)。
例如研發(fā)比較關注機器的 CPU、內(nèi)存、硬盤,產(chǎn)品和運營比較關注運營層面的指標,例如新增用戶數(shù),日活等,都可以通過 Prometheus 和 grafana 簡單,直觀化展示。
例如下圖 JVM 的監(jiān)控。
業(yè)務實踐背景
公司某個業(yè)務需要 n 個評審專家對同一批 n 張業(yè)務報表批量簽字。3 方簽字接口只有支持單個報表簽字,所以需要 n*n
次,單次簽字邏輯復雜,流程較長,所有后臺用線程池做了異步化。
簽字作為業(yè)務的核心節(jié)點,不能有故障。所以怎么監(jiān)控線程池的關鍵指標,實現(xiàn)動態(tài)調(diào)整參數(shù),當任務數(shù)量過多告警,是一個需要解決的痛點。
我們通過 Prometheus 自定義線程池的指標,grafana 展示,apollo 動態(tài)調(diào)整線程池的變量,實現(xiàn)彈性擴展。
實踐
線程池參數(shù)動態(tài)更新
通過接入 apollo 配置,當檢測到線程池的配置變化時,重新設置:
- 核心線程數(shù)
- 最大線程數(shù)
- 修改線程空閑時間
@Component public class ApolloRefreshConfig { @Resource private RefreshScope refreshScope; @Resource private ApplicationContext applicationContext; @Resource private ThreadPoolExecutor executorService; @ApolloConfigChangeListener public void onChange(ConfigChangeEvent changeEvent) { applicationContext.publishEvent(new EnvironmentChangeEvent(changeEvent.changedKeys())); refreshScope.refreshAll(); // 刷新變量 asyncRequestTaskConfigChange(changeEvent.changedKeys()); } private void asyncRequestTaskConfigChange(Set<String> changedKeys) { //apollo 變更的是線程池變量 if (changedKeys.contains(EvaluationProcessAsyncRequestTaskConfig.ASYNC_REQUEST_TASK_CHANGE_FLAG_KEY)) { // 核心線程數(shù) Integer corePoolSizeOld = executorService.getCorePoolSize(); if (!corePoolSize.equals(corePoolSizeOld)) { executorService.setCorePoolSize(corePoolSize); } // 最大線程數(shù) Integer maximumPoolSizeOld = executorService.getMaximumPoolSize(); if (!maximumPoolSize.equals(maximumPoolSizeOld)) { executorService.setMaximumPoolSize(maximumPoolSize); } // 修改線程空閑時間 Long keepAliveTimeOld = executorService.getKeepAliveTime(TimeUnit.MINUTES); if (!keepAliveTime.equals(keepAliveTimeOld)) { executorService.setKeepAliveTime(keepAliveTime, TimeUnit.MINUTES); } } } }
線程池指標上報
在 springboot 版本 2.X 版本以后,使用 Prometheus 進行監(jiān)控,只需引入 Spring Boot Actuator 相關的 jar,就可以簡單集成,然后我們就可以自定義業(yè)務指標,上報 Prometheus 了
<dependency> <groupId>cn.gov.zcy.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency
Prometheus 中的核心類 io.micrometer.core.instrument.MeterRegistry 中可以定制各種業(yè)務指標,也有封裝的例如計數(shù)類 Counter,這里引用一個 Gauge 只定義的指標
@Component public class MonitorFactory { @Resource private MeterRegistry meterRegistry; @Resource private ThreadPoolExecutor threadPoolExecutor; private ThreadPoolSizeMonitor threadPoolSizeMonitor = new ThreadPoolSizeMonitor(threadPoolExecutor); class ThreadPoolSizeMonitor implements ToDoubleFunction { private ThreadPoolExecutor executor; //計數(shù) private AtomicDouble monitor = new AtomicDouble(0); public Object getMonitor() { return monitor; } public ThreadPoolSizeMonitor(ThreadPoolExecutor executor) { this.executor = executor; } @Override public double applyAsDouble(Object o) { monitor.set(executor.getPoolSize()); return monitor.get(); } } //上報指標,初始化時注冊指標 @PostConstruct public void monitorThreadPool() { // 當前存活線程數(shù) Gauge.builder("ReportBatchSignPool_poolSizeMonitor", threadPoolSizeMonitor.getMonitor(), threadPoolSizeMonitor).register(meterRegistry); // 當前活躍(忙碌)線程數(shù) // 核心存活線程數(shù) // 提交的任務數(shù) // 執(zhí)行完畢的任務數(shù) // 任務隊列積壓監(jiān)控 } //1 分鐘更新一次指標數(shù)據(jù) @Scheduled(cron = "0 0/1 * * * ?") public void publishWatcher() { threadPoolSizeMonitor.applyAsDouble(null); } }
Prometheus 指標展示
用 Prometheus quering 語句查詢出具體數(shù)值 最后一列展示向量結(jié)果 16,查詢語法如下
grafana 可視化展示
告警配置
grafana 配置告警,配置具體的通知信息,觸發(fā)規(guī)則,告警的通知渠道 參考官方文檔
通知到叮叮告警群
總結(jié)
本文介紹了研發(fā)人員通過配置 Prometheus 自定義的業(yè)務指標,實現(xiàn)監(jiān)控告警完整鏈路的大致的流程。大家也可以定制化除了系統(tǒng)指標(例如 CPU、JVM、IO 等)外,梳理出自己系統(tǒng)的核心業(yè)務,添加告警,增強系統(tǒng)的穩(wěn)定性,做到未雨綢繆,防患于未然。
參考文獻
以上就是業(yè)務系統(tǒng)的Prometheus實踐示例詳解的詳細內(nèi)容,更多關于Prometheus業(yè)務系統(tǒng)的資料請關注腳本之家其它相關文章!
相關文章
Java8實現(xiàn)對List<Integer>的求和
這篇文章主要介紹了Java8實現(xiàn)對List<Integer>的求和方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-05-05SpringBoot中實現(xiàn)@Scheduled動態(tài)定時任務
SpringBoot中的@Scheduled注解為定時任務提供了一種很簡單的實現(xiàn),本文主要介紹了SpringBoot中實現(xiàn)@Scheduled動態(tài)定時任務,具有一定的參考價值,感興趣的可以了解一下2024-01-01