一、背景介绍
HikariCP 作为一款高性能的 JDBC 连接池,性能远高于 druid、 c3p0、 tomcat 等连接池。大小却只有 130 Kb,做到了非常的轻量级。一直作为 Java 技术风向标的 Spring 也在 Spring boot 2.0 版本开始将 HikariCP 作为其默认的 JDBC 连接池。
HikariCP 作者给出的性能测试数据显示也是远超其它连接池。
HikariCP 的国外用户也是一致好评。
掌门教育技术部也是紧跟技术趋势,生产连接池从原 Alibaba Druid 统一切换到了 HikariCP,在不增加硬件成本的前提下提升了服务性能。
但是,生产环境仅仅只是简单使用还不够,数据库连接池这块缺乏详细的监控和告警,当请求流量激增,出现慢 SQL 等都会导致大量连接被占用,从而出现服务不可用的情况。当前闲置的连接数是多少?活跃连接数是多少?获取连接耗时情况是多少?不可见,缺乏详细监控,不利于观测、调优、问题排查。连接池可用连接耗尽了,连接获取超时了,活跃连接数超过 90% 了,不能设置详细指标进行告警。
二、方案研究
目前公司生产监控和告警是基于 cncf 的 Prometheus 来构建的, Prometheus 作为一套开源的监控、报警、时序数据库的组合,被许多公司和组织接受和采用,它是 Google 内部的 BorgMon 监控系统的相似实现。现在最常见的 Kubernetes 容器管理系统中,通常会搭配 Prometheus 进行监控。
Prometheus 整体架构如下:
Prometheus 主要通过 pull metrics 的方式采集服务监控指标数据,存入自己的时序数据库,通过配置 Grafana 查看业务监控指标,通过 AlertManager 提供业务指标告警。
方案一:
公司目前Java服务基本都是基于 Spring Boot 项目, Spring Boot 2.x 默认连接池就是 HikariCP,本身自带的 Spring Boot Actuator 就提供了非常丰富完善的监控指标。直接开启 Actuator 的配置就能使用,简单方便。
支持 Web 和 JMX 两种方式暴露指标
但是, Actuator 生产报过安全漏洞,存在重大的安全隐患,安全部门明令禁止使用。
如果强行使用 Actuator 方式,需要和安全部沟通和评估,还需对多个生产使用的 Actuator 版本进行安全测试,如发现 Actuator 漏洞需要及时修复。
方案二:
HikariCP 从 2.2.0+ 开始就支持 Dropwizard 收集 Metrics,通过配置 MetricRegistry 开启 Metrics 指标的记录。
官方提供的核心指标包括:
pool.Wait : 从连接池中获取连接等待了多久。
pool.Usage : 连接从连接池中取出使用了多久才归还。
pool.TotalConnections : 连接池中共有多少连接。
pool.IdleConnections : 连接池中有多少闲置连接。
pool.ActiveConnections : 连接池中有多少活跃连接。
pool.PendingConnections : 有多少线程等待从池中获取连接。
HikariCP 指标埋点源码研究:
1、获取连接时的指标埋点:
当调用 getConnection() 从连接池中获取连接时,记录了连接实体的借用状态指标和借用超时的状态指标。
2、创建超时时的指标埋点:
当从连接池中获取连接超时时,会创建一个超时的 SQLException 并记录连接获取超时指标。
3、新建数据库连接时的指标埋点:
当连接池中的连接不够需要创建新的连接时,会调用 newConnection() 方法创建新连接并记录连接创建指标。
4、HikariCP 定义了统一的指标跟踪抽象接口 ( IMetricsTrackerDelegate ):
该抽象接口定义了抽象方法,对指标的记录方法进行了统一的抽象。
有 2 个实现类 NopMetricsTrackerDelegate 和 MetricsTrackerDelegate 类。
NopMetricsTrackerDelegate 为空实现,什么都没干。
MetricsTrackerDelegate 对接口 IMetricsTracker 做了一层封装。
通过对是否 MetricsTrackerFactory 为空判断,是否需要进行 metricsTracker
IMetricsTracker 又定义了统一的指标跟踪抽象接口
不同的 Metrics 实现组件实现统一的抽象
经过研究,可以使用 Dropwizard 作为metrics 指标收集的实现,通过指标转换为 Prometheus 能识别的 metrics 提供给 Prometheus 进行数据收集,从而达到监控和告警的目的。
三、落地实战
因为方案一安全的原因,最终选择了方案二进行落地。为了对 HikariCP 的指标收集实现统一和复用,封装了统一的 jar 包提供给业务应用服务使用。只需要简单的添加一个 maven 依赖,就能自动提供指标数据。
1、部分源码实现如下:
使用 spring boot auto configuration 自动加载和注入实现
使用 Dropwizard 的 DropwizardExports 暴露指标数据
使用 Prometheus Client 对Dropwizard 数据格式做转换,转成 Prometheus 格式
2、转换后的指标效果:
3、生产监控效果:
通过 Grafana 看板查看生产实例连接池指标情况
4、生产告警效果:
用线上单个告警指标为例,当前活跃连接数大于总连接数 80% 的时候进行告警,通知到服务实例对应的负责人。
掌控告警
掌控是掌门自研的,为研发提供生产监控、告警处理的手机 App。支持对告警信息进行推送和处理。
短信告警
四、作者介绍
邢智宇,掌门业务系统研发部研发工程师,热爱开源技术,擅长结合热门技术栈解决技术问题。
特别感谢:掌门系统研发部 devops 工程师 贾平 的大力支持。
---------- END ----------
加入掌门
欢迎大佬们加入掌门教育大家庭,一起畅谈技术,分享交流。在招职位有研发工程师/架构师( Web
前端/ Java
/ iOS
)、音视频工程师/架构师( iOS
、安卓、 PC
端)、大数据工程师、算法工程师、逆向工程师( iOS
、安卓、 PC
端)。
投递信箱:zeying.shi@zhangmen.com 施老师。
往期好文