开发者

业务系统的Prometheus实践示例详解

目录
  • 什么是 Prometheus
  • 业务实践背景
  • 实践
    • 线程池参数动态更新
    • 线程池指标上报
    • Prometheus 指标展示
    • grafana 可视化展示
    • 告警配置
  • 总结

    开发者_JS开发什么是 Prometheus

    Prometheus(普罗米修斯)是古希腊的一个神明,名字的意思是「先见之明」。从它的名字可以看出,Prometheus 是做「先见之明」的监控告警用途。

    官网描述为From metrics to insight,用指标洞察系统。

    Prometheus 其实就是一个数据监控解决方案,它能帮你简单快速地搭建起一套可视化的监控系统。

    例如研发比较关注机器的 CPU、内存、硬盘,产品和运营比较关注运营层面的指标,例如新增用户数,日活等,都可以通过 Prometheus 和 grafana 简单,直观化展示。

    例如下图 JVM 的监控。

    业务系统的Prometheus实践示例详解

    业务实践背景

    公司某个业务需要 n 个评审专家对同一批 n 张业务报表批量签字。3 方签字接口只有支持单个报表签字,所以需要 n*n 次,单次签字逻辑复杂,流程较长,所有后台用线程池做了异步化。

    签字作为业务的核心节点,不能有故障。所以怎么监控线程池的关键指标,实现动态调整参数,当任务数量过多告警,是一个需要解决的痛点。

    我们通过 Prometheus 自定义线程池的指标,grafana 展示,apollo 动态调整线程池的变量,实现弹性扩展。

    实践

    线程池参数动态更新

    通过接入 apollo 配置,当检测到线程池的配置变化时,重新设置:

    • 核心线程数
    • 最大线程数
    • 修改线程空闲时间
    @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)) {
                // 核心线程数
                Integer corePoolSizeOld = executorService.getCorePoolSize();
                if (!corePoolSize.equals(corePoolSizeOld)) {
                    executorService.setCorePoolSize(corePoolSize);
                }
                // 最大线程数
                Integer maximumPoolSizeOld = executorService.getMaximumPoolSize();
            http://www.devze.com    if (!maximumPoolSize.equals(maximumPoolSizeOld)) {
                    executorService.setMjavascriptaximumPoolSize(maximumPoolSize);
                js}
                // 修改线程空闲时间
                Long keepAliveTimeOld = executorService.getKeepAliveTime(TimeUnit.MINUTES);
                if (!keepAliveTime.equals(keepAliveTimeOld)) {
                    executorService.setKeepAliveTime(keepAliveTime, TimeUnit.MINUTES);
                }
            }
        }
    }
    

    线程池指标上报

    FFgbvV springboot 版本 2.X 版本以后,使用 Prometheus 进行监控,只需引入 Spring Boot Actuator 相关的 jar,就可以简单集成,然后我们就可以自定义业务指标,上报 Prometheus 了

    <dependency>
        <groupId>cn.gov.zcy.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency
    

    Prometheus 中的核心类 io.micrometer.core.instrument.MeterRegistry 中可以定制各种业务指标,也有封装的例如计数类 Counter,这里引用一个 Gauge 只定义的指标

    @Component
    public class MonitorFactory {javascript
        @Resource
        private MeterRegistry meterRegistry;
        @Resource
        private ThreadPoolExecutor threadPoolExecutor;
        private ThreadPoolSizeMonitor threadPoolSizeMonitor = new ThreadPoolSizeMonitor(threadPoolExecutor);
        class ThreadPoolSizeMonitor implements ToDoubleFunction {
            private ThreadPoolExecutor executor;
            //计数
            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() {
            // 当前存活线程数
            Gauge.builder("ReportBATchSignPool_poolSizeMonitor", threadPoolSizeMonitor.getMonitor(), threadPoolSizeMonitor).register(meterRegistry);
            // 当前活跃(忙碌)线程数
            // 核心存活线程数
            // 提交的任务数
            // 执行完毕的任务数
            // 任务队列积压监控
        }
        //1 分钟更新一次指标数据
        @Scheduled(cron = "0 0/1 * * * ?")
        public void publishWatcher() {
            threadPoolSizeMonitor.applyAsDouble(null);
        }
    }
    

    Prometheus 指标展示

    用 Prometheus quering 语句查询出具体数值 最后一列展示向量结果 16,查询语法如下

    prometheus.io/docs/promet…

    业务系统的Prometheus实践示例详解

    grafana 可视化展示

    业务系统的Prometheus实践示例详解

    告警配置

    grafana 配置告警,配置具体的通知信息,触发规则,告警的通知渠道 参考官方文档

    grafana.com/docs/grafan…

    业务系统的Prometheus实践示例详解

    业务系统的Prometheus实践示例详解

    通知到叮叮告警群

    总结

    本文介绍了研发人员通过配置 Prometheus 自定义的业务指标,实现监控告警完整链路的大致的流程。大家也可以定制化除了系统指标(例如 CPU、JVM、IO 等)外,梳理出自己系统的核心业务,添加告警,增强系统的稳定性,做到未雨绸缪,防患于未然。

    参考文献

    Prometheus 官方文档

    grafana 告警 文档

    以上就是业务系统的Prometheus实践示例详解的详细内容,更多关于Prometheus业务系统的资料请关注我们其它相关文章!

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜