QuXiao's Blog

Life && Tech && Thoughts

Open-Falcon 源码阅读(一)整体架构 & Agent

Written on

之前在调研OS监控系统,众所周知,其中比较老牌的就是Zabbix了,我们团队的初创阶段使用的是Zabbix。但是从实际使用过程中会发现,虽然这套系统足够简单、经典,但是从架构、存储、展现等方面,还是有许多不足的。在寻找有什么其它的OS监控系统的时候,Open-Falcon进入了我的视野,这个系统是由小米运维部的同学开发的,slogan是『人性化的互联网企业级监控系统』,在开源社区也颇为活跃。

架构

官网架构图如下:

其中:

  • Falcon-agent:部署在需要监控的服务器上,采集机器本身的性能数据,此外,还会定期执行用户配置的脚本,以及接收来自第三方的数据。最终,将这些数据都发送至Transfer模块。
  • HBS(heartbeat server):接收所有Falcon-agent的分钟频率的心跳请求,上报Agent自身的信息,HBS会同步一些数据给Agent,包括:需要监控的端口、进程、需要执行的脚本等信息,另外,HBS还会和Judge模块进行通信,同步策略。最终,该模块就变成了一个『数据库缓存』,将数据库中的内容加载至内存,等待其它模块的请求。
  • Transfer:接收来自Falcon-agent的采集数据,将数据转发至Judge、Graph、OpenTSDB。
  • Graph:通过Transfer接收Agent采集的数据,将数据进行持久化保存至RRD数据库,并提供接口进行数据查询。
  • Query:接收来自用户或者Dashboard的请求,将请求分发至对应的Graph模块,再将查询结果进行合并。
  • Judge:用于判断是否触发告警条件的模块,一方面从Transfer接收Agent采集的数据,一方面请求HBS同步策略列表。Judge模块将接收到的数据组织成长度固定的链表,每接收到一份数据,就将对应的策略进行判断 。
  • Alarm:Alarm从redis中获取告警事件信息,根据告警事件信息,进行发送短信、邮件、URL callback等操作(具体发送短信和邮件的操作不在Alarm中完成,Alarm只是将操作信息发送至redis,具体操作由使用方实现)。另外,Alarm还会将低优先级的事件进行合并,然后再一并发出。
  • Web Portal:用于用户配置告警策略的界面。
  • Dashboard:展现数据查询图表的Web界面。
  • Aggregator:集群聚合模块。聚合某集群下的所有机器的某个指标的值,提供一种集群视角的监控体验。

Agent

配置介绍

配置文件的加载过程,使用Golang的结构体tag标签 + JSON解码器,将JSON直接解析至Struct,Open-falcon的大部分模块均使用这种conf解析方式,比较方便,后面的模块讲解就不再赘述了。

配置文件(JSON格式)

内部Struct结构 (注意,Struct字段的JSON tag与上面配置文件的JSON字段一一对应。)

配置文件中,主要配置以下内容:

  • 采集数据的脚本更新地址
  • 指定了Agent的上游模块的地址,包括heartbeat和transfer模块
  • agent开放的HTTP端口
  • 采集数据的过滤条件

上报数据

数据格式

由于数据存储的最终载体是RRD数据库,所以上报的数据格式与RRD保持一致,格式如下:

其中,Step和CounterType中RRD中的概念。Step就是数据采集的间隔,单位为秒。而CounterType分为五个类型,分别如下表:

  • COUNTER: 必须是递增的,除非是计数器溢出(overflows)。在这种情况下,RRDtool 会自动修改收到的值。例如网络接口流量、收到的packets 数量都属于这一类型。
  • DERIVE: 和 COUNTER 类似。但可以是递增,也可以递减,或者一会增加一会儿减少。
  • ABSOLUTE: ABSOLUTE 比较特殊,它每次都假定前一个interval的值是0,再计算平均值。
  • GAUGE: GAGUE 和上面三种不同,它没有“平均”的概念,RRDtool 收到值之后字节存入 RRA 中。
  • COMPUTE: COMPUTE 比较特殊,它并不接受输入,它的定义是一个表达式,能够引用其他DS并自动计算出某个值。

数据内容

上报的采集数据分为三类:内置采集数据、Plugin采集数据、第三方采集数据。 内置采集数据,表示服务器操作系统层面的性能数据,例如CPU、内存、网络、磁盘空间等。另外,内置采集数据还包括端口存活、URL可访问性等定制的数据。具体的内容可以从以下代码的注释看得比较清楚:

        Mappers = []FuncsAndInterval{
    FuncsAndInterval{
        Fs: []func() []*model.MetricValue{
            AgentMetrics,        // agent存活标志 agent.alive
            CpuMetrics,          // CPU
            NetMetrics,          // 网卡信息,例如:net.if.in.bytes
            KernelMetrics,       // 内核信息,例如:kernel.maxfiles / kernel.maxproc
            LoadAvgMetrics,      // 负载信息
            MemMetrics,          // 内存
            DiskIOMetrics,       // 磁盘IO原始信息,例如:disk.io.read_requests
            IOStatsMetrics,      // 磁盘IO统计信息,例如:disk.io.read_bytes / disk.io.await
            NetstatMetrics,      // TCP统计信息,例如:TcpExt.PruneCalled / TcpExt.TCPPrequeueDropped TODO
            ProcMetrics,         // 进程数信息,通过tag区分不同进程
            UdpMetrics,          // /proc/net/snmp 中的udp信息,例如:InDatagrams / NoPorts
        },
        Interval: interval,
    },
    FuncsAndInterval{
        Fs: []func() []*model.MetricValue{
            DeviceMetrics,        // 磁盘空间信息
        },
        Interval: interval,
    },
    FuncsAndInterval{
        Fs: []func() []*model.MetricValue{
            PortMetrics,              // 侦听的端口信息
            SocketStatSummaryMetrics, // TCP socket统计信息,例如:establish / closed / timewait,使用『ss -s』命令
        },
        Interval: interval,
    },
    FuncsAndInterval{
        Fs: []func() []*model.MetricValue{
            DuMetrics,                  // 某个目录下的空间大小,使用『du -bs』命令
        },
        Interval: interval,
    },
    FuncsAndInterval{
        Fs: []func() []*model.MetricValue{
            UrlMetrics,                  // URL可访问性
        },
        Interval: interval,
    },
}

其中,Plugin采集数据,其实过程就是定期执行一些脚本,再把脚本的输出结构解析为MetricValue格式,最终从Agent发送至Transfer,可以把Plugin理解为一系列crontab任务。 第三方采集数据,是通过Agent提供的HTTP服务,将采集数据(来自与其它业务程序)发送过来。

同步数据

每隔一分钟,Agent会与HBS进行一系列RPC通信,上报自己的状态,并且获取一些自己需要的数据。

向HBS汇报的数据:

  • HostName
  • IP (cfg中的IP,或者本机的IP)
  • Agent版本
  • Plugin版本(脚本所在git目录的版本,git rev-parse HEAD)

从HBS获取的数据:

  • Plugin信息,需要以什么频率运行什么脚本

  • 内置采集信息
    • URL_CHECK_HEALTH,需要定期检查哪些URL
    • NET_PORT_LISTEN,需要检查哪些端口的存活
    • DU_BS,需要检查哪些文件夹的占用空间
    • PROC_NUM,需要检查哪些进程的存活
  • 信任的IP列表(执行远程命令时需要检查)

对外服务

除了上面提到的正常的与HBS同步数据,上报数据至Transfer,Agent还开启了HTTP服务,用于管理者远程对Agent进行操作或者获取Agent的信息。

具体有以下几种服务:

  • Admin命令
    • Agent进程退出
    • 重新加载配置
    • 返回工作目录
    • 返回信任的IP列表)
  • 返回目前采集的数据
    • CPU、磁盘、IO、内存……
  • Plugin(使用git同步远端的脚本)

  • 接收其它模块Push数据

  • 运行任意用户命令

  • 运行系统命令:date, uptime, loadavg

其中,所有执行命令以及Agent状态更新操作,都需要调用方IP在信任IP列表中。

-- EOF --

comments powered by Disqus