作者| 姜闻名
起源|尔达 Erda 公众号
导读:为了让大家更好的理解 MSP 中 APM 零碎的设计实现,咱们决定编写一个《详聊微服务观测》系列文章,深刻 APM 零碎的产品、架构设计和根底技术。本文为该系列文章的第三篇,将次要对 Telegraf 数据处理链路的实现原理以及插件实现形式进行介绍。
《详聊微服务观测》系列文章:
- 《从监控到可观测性,咱们最终要走向哪里?》
- 《上手后才晓得,这套仪表盘零碎用起来是真的爽!》
- 《一文搞懂指标采集利器 Telegraf》(本文)
Telegraf 是 InfluxData 公司开源的一款非常风行的指标采集软件,在 GiHub 已有上万 Star。其借助社区的力量,领有了多达 200 余种采集插件以及 40 余种导出插件,简直笼罩了所有的监控项,例如机器监控、服务监控甚至是硬件监控。
架构设计
Pipeline 并发编程
在 Go 中,Pipeline 并发编程模式是一种罕用的并发编程模式。简略来说,其整体上是由一系列阶段(stage),每个 stage 由一组运行着雷同函数的 goroutine 组成,且各个 stage 之间由 channel 相互连接。
在每个阶段中,goroutine 负责以下事宜:
- 通过入口 channel,接管上游 stage 产生的数据。
- 解决数据,例如格局转换、数据过滤聚合等。
- 通过进口 channel,发送解决后的数据到上游 stage。
其中,每个 stage 都同时领有一个或多个进口、入口 channel,除了第一个和最初一个 stage,其别离只有进口 channel 和入口 channel。
Telegraf 中的实现
Telegraf 采纳了这种编程模式,其次要有 4 个 stage,别离为 Inputs、Processors、Aggregators 和 Outputs。
- Inputs:负责采集原始监控指标,包含被动采集和被动采集。
- Processors:负责解决 Inputs 收集的数据,包含去重、重命名、格局转换等。
- Aggregators:负责聚合 Processors 解决后的数据,并对聚合后的数据计算。
- Outputs:负责接管解决 Processors 或 Aggregators 输入的数据,并导出到其余媒介,例如文件、数据库等。
且它们彼此之间也是由 channel 互相链接的,其架构图如下所示:
能够看到,其整体上采纳的就是 pipeline 并发编程模式,咱们简略介绍下它的运作机制:
- 第一个 stage 为 Inputs,每个 input 生成一个 goroutine,各自采集数据并扇入(fan-in)到 channel 中。
- 第二个 stage 为 Processors,每个 processor 生成一个 goroutine,并按程序彼此用 channel 连贯。
- 第三个 stage 为 Aggregators,每个 aggregator 生成一个 goroutine,并生产 Processors 产生的数据,并扇出(fan-out)到各个 aggregator。
- 最初一个 stage 为 Outputs,每个 output 生成一个 goroutine,并生产由 Processors 或 Aggregators 产生的数据,并扇出到各个 output。
扇入(fan-in):多个函数输入数据到一个 channel,并由某个函数读取该 channel 直到其被敞开。
扇出(fan-out):多个函数读取同一个 channel 直到其被敞开。
插件设计
Telegraf 领有如此泛滥的 input、output 以及 processor 插件,那么它是如何高效地治理这些插件呢?并且又是如何设计插件体系以应答一直激增的扩大需要呢?别急,请容我细说。
其实,这里的插件并非通常意义上的插件(即在运行时动静加载与绑定动态链接库),而是一种基于工厂模式的变体,首先咱们来看下 Telegraf 的插件目录构造:
plugins
├── aggregators
│ ├── all
│ ├── basicstats
│ ├── registry.go
...
├── inputs
│ ├── all
│ ├── cpu
│ ├── registry.go
...
├── outputs
│ ├── all
│ ├── amqp
│ ├── registry.go
...
├── processors
│ ├── all
│ ├── clone
│ ├── registry.go
...
由上能够看到,目录构造是有法则的(以下咱们均以 Inputs 的插件为例,其余模块实现相似)。
- plugins/inputs:为各个 input 插件的包目录。
- plugins/inputs/all:通过 import 的形式引入插件模块包(次要是为了防止循环援用)。
- plugins/inputs/registry.go:寄存注册表以及相干函数。
接口申明
Telegraf 通过 interface 来申明如下 Input 接口,示意 Input:
接口实现
在 plugins/inputs/ 目录中创立插件,例如 cpu,实现 Input 接口:
注册插件
最初,咱们只须要往全局注册表中注册插件的工厂函数即可:
如此,泛滥插件就被井井有条的治理起来了。同时,扩大插件也很不便,只需实现 Input 接口并注册工厂函数即可。
Erda 中的利用
在 Erda 中,咱们应用 Telegraf 作为 Erda 平台的指标采集服务,以守护过程的形式部署在每台物理机上。现如今,已广泛应用生产,在上千台机器上稳固运行,采集并上报大量指标,以供 SRE 及相干运维人员不便地剖析与排查。
因为一些非凡的需要,咱们不得不基于 Telegraf 进行了二次开发,以便更好的适配业务需要。尽管如此,得益于 Telegraf 弱小的插件零碎,咱们往往只须要针对需要新增插件即可。例如,减少 output 插件以上报到咱们本人的收集端,减少 intput 插件查看 Erda 本身组件衰弱度等。
后续,咱们将逐步摈弃二开局部,拥抱开源,最大化地与 Telegraf 官网开源版本保持一致,以回馈社区。
参考
- 《Go Concurrency Patterns: Pipelines and cancellation》
- Telegraf 我的项目地址
- 《联合我的项目聊一聊 Go 的工厂模式》
如果你有任何疑难,欢送增加小助手微信(Erda202106)退出交换群,参加交换和探讨!
- Erda Github 地址:https://github.com/erda-project/erda
- Erda Cloud 官网:https://www.erda.cloud/