業(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ù)值 最后一列展示向量結果 16,查詢語法如下

grafana 可視化展示

告警配置
grafana 配置告警,配置具體的通知信息,觸發(fā)規(guī)則,告警的通知渠道 參考官方文檔


通知到叮叮告警群
總結
本文介紹了研發(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)的資料請關注腳本之家其它相關文章!
相關文章
javax.mail.SendFailedException: Sending failed問題原因
這篇文章主要介紹了javax.mail.SendFailedException: Sending failed問題原因,需要的朋友可以參考下2015-05-05
Activiti7通過代碼動態(tài)生成工作流實現(xiàn)詳解
這篇文章主要為大家介紹了Activiti7通過代碼動態(tài)生成工作流實現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-11-11
Spring Cloud微服務架構的構建:分布式配置中心(加密解密功能)
這篇文章主要給大家介紹了關于Spring Cloud微服務架構的構建:分布式配置中心(加密解密)的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用具有一定的參考學習價值,需要的朋友可以參考下2018-05-05
Java多線程中線程的兩種創(chuàng)建方式及比較代碼示例
這篇文章主要介紹了Java多線程中線程的兩種創(chuàng)建方式及比較代碼示例,簡單介紹了線程的概念,并行與并發(fā)等,然后通過實例代碼向大家展示了線程的創(chuàng)建,具有一定參考價值,需要的朋友可以了解下。2017-11-11
Mybatis SqlSessionFactory與SqlSession詳細講解
SqlSessionFactory是MyBatis的核心類之一,其最重要的功能就是提供創(chuàng)建MyBatis的核心接口SqlSession,所以我們需要先創(chuàng)建SqlSessionFactory,為此我們需要提供配置文件和相關的參數(shù)2022-11-11

