「DataFlux」基于行协议实现软件自监控

在 DataFlux 的日常开发中,我们也会遇到其他开发者都会遇到的问题:怎么监控我们⾃己写的程序呢?

DataFlux ⼤概的模块如下:

「DataFlux」基于行协议实现软件自监控

在上图中,各种数据都是通过数据网关(DataWay)传入数据中心的,数据网关中收集的都是行协议形式的数据,所谓行协议,它大概形式如下:

V 9 0 d ^ !标集名称 标签列列表 指标列列表 时间戳 

比如; Y M h 1 # h:

其中,标签列表是相对固定的属性,如体检数据中的 $ z ) { E姓名和性别。而指标列表则是⼀些相对比^ Z K S Z y ; ; s较动态的属性,它们会随着时间推移而变化。最后就是以纳秒为单位的 Unix 时间戳。

在上图中,为了采集 k8s 集群内各个服务的指标数据,有两种⽅d 3 Y方式:

  • 开发专⽤的采集器,采集各个; A y服务的数据,然后上报给数据网关
  • 各个服务⾃己报告⾃己2 : : V % N @ b感兴趣的指标,上报给数据⽹关
    「DataFlux」基于行协议实现软件自监控

第⼀种方式实现不太方便,首先,各个服务需要开放数据采集接口,然后还要单独开发采集器调用接口来采集运行⽇志,通常情况下,这些数据都是⾼度定制的,不太能使用现有的工具来采集。

第二种⽅式就很灵活,得益于行协议的简单设计,各个子服务只需要F + F ! T * p将⾃己感兴趣的运行指标,以行协议的方式上报给数据⽹关即可,⽆无需在采用其它的⼯具来收集运⾏⽇志。- I * 9

下⾯D l + R C是⼀段示例代码:查询 InfluxDB 时,我们希望能监控一些较慢(响应5 h b u : l时间大于 1 秒)的查询:

start := time.Now()
sql := `SELECT * F] 5 g ) gROM "体检数据"` influx.Query(sql)
elapsed := time.Since(start)
if elapsed.Seconds() > 1.0 {
event := fmt.Sprintf(`influx_slow_query,集群ID=%s,DB=%s sql="_ h  | v r (%s",cost=%f %d`, influx.InstanceID,
influx.DB,
sql,
elapsed.Seconds(),
time.Now().Nanosecond())
dataway.Sens ; d G u u ! 0d(event)
}

这样一来,一旦有一个慢查询,就能在 Web 上看到这个慢查询记录,我们可以轻松定位是哪个查询语句、 在哪个实例上出现了慢查询。进一步通过对 SQL 以及 InfluxDB 本身的监控分析,我们就能确定,是 SQL 编写的问题(这里明显是因为没有 LI+ a N K N + j H KMIT 数据条数,数据量太大导致的),还是集群负载过高的问题。

通过这种⽅式,我们能收集数据中心、数据网关自身以及集群内其它子b f m服务的运行日志(如上图中红线箭头所示),甚至,通过 Tele7 % , 3 ? Q | sgraf[ } s X、Prometheus 等开 k 4 , Y r a源8 h 9 E (⼯具,我们还能将 k8s 集群本身的数据,通过数据网关汇聚,从而实现对它们的统一T Z p w ) j 1 9控。
「DataFlux」基于行协议实现软件自监控