我们都知道,在监控领域,常见的数据采集方式分为
- push:数据源服务主动向监控平台推送数据
- pull:监控平台轮训向数据源服务拉取数据
- push 和 pull 组合模式
下面先来看看业界比较流行的两大监控平台
Prometheus
Prometheus是在微服务和容器化的过程中兴起,算是当前监控领域的经典,尤其是与K8s的搭配也是成为了云原生体系组件的事实标准。其中对于指标数据的定义也是被大家所接受。
一开始的时候Prometheus也是先实现的Pull方式,后期也补充了Push的方式,但明显更推荐Pull方式,exporter的采集器,k8s中的serviceMonitor
每一个被Prometheus监控的服务都是一个Job,Prometheus为这些Job提供了官方的SDK ,利用这个SDK可以自定义并导出自己的业务指标,也可以使用Prometheus官方提供的各种常用组件和中间件的Exporter(比如常用的MySQL,Consul等等)。对于短时间执行的脚本任务或者不好直接Pull指标的服务,Prometheus提供了PushGateWay网关给这些任务将服务指标主动推Push到网关,Prometheus再从这个网关里Pull指标。
Opentelemetry
OpenTelemetry是一个开源的可观测性框架,它由一系列的工具、协议、API 和 SDK 组成,使 IT 团队能够检测、生成、收集和导出观测数据以便进行分析和了解软件的性能和行为。
而对于如何收集和发送可观测性数据的通用格式和标准正是OpenTelemetry所发挥作用的地方。作为云原生计算基金会 (CNCF) 的孵化项目,OpenTelemetry旨在提供与供应商无关的统一库和 API 集——主要用于收集数据并将其传输到某个地方。
OpenTelemetry是用于收集观测数据并将其导出到目标系统的专用协议。由于 CNCF 项目本身是开源的,因此最终目标是使数据收集比目前更加与系统解耦。OpenTelemetry是如何工作的呢?
分为三部分:
- Client端:包括OpenTelemetry的各语言SDK以及数据收集器(包括OpenTelemetry的Collector以及其他任何开源或商业化的收集器)。此外,还包括用户可以基于OTLP的API通过gRPC或HTTP形式上报数据。
- Collector:细分为三个组件组成,分别是: Receiver:接收器可以是基于推式或拉式的,它是数据进入Collector的方式,它可以是暴露某个特殊的协议接口,但是可以完成兼容OTLP的协议转换。任何人都可以扩展自己的Receiver。 Processor:处理器在接收和导出之间的数据上运行,并且是可选的。例如可以设置限流、资源限制、数据格式转换、数据富化等等,并且也支持扩展。 Exporter:这是可以基于推或拉的导出器是我们将数据发送到一个或多个后端/目的地的方式。是OTLP数据转换某个特殊协议的关键组件,我们可以根据需要任意定义它。
- Back-end:它其实是独立于OpenTelemetry之外的存储后端,可以是开源的组件例如Prometheus、InfluxDB等,也可以是CLS、Splunk等。
https://zhuanlan.zhihu.com/p/74930691 https://github.com/open-telemetry/docs-cn/blob/main/OT.md https://lib.jimmysong.io/opentelemetry-obervability/architectural-overview/ https://skald.top/2020/12/31/opentelemetry-intro/ https://jckling.github.io/2021/04/02/Jaeger/OpenTelemetry 规范阅读/
从上面可以看出,各个监控平台或多或少都提供了push和pull模式的监控方式,下面来分析下两种方式的区别
工作原理
原理对比 | Pull | Push |
---|---|---|
配置管理 | 中心化配置 | 1. 端上静态配置2. 通过配置中心获取配置 |
监控对象发现 | 1. 静态2. 依赖服务发现机制 如k8s,CMDB等 | 由应用自主上报,无需服务发现模块 |
部署方式 | 1. 应用直接暴露端口,接入服务发现2. 服务不直接暴露端口的,如MYSQL依赖适配器(Exporter) | 应用主动推送到监控系统 |
可扩展性 | 1. 依赖Pull端扩展;2. 需要Pull Agent和存储解耦(原生Prometheus不支持) | 简单,只需要中心接收端横向扩展 |
要想正确的选择,需要先了解Pull和Push的工作原理,这里的关键区别点就在于监控对象是如何来发现的,Pull就需要提前得到目标地址列表,为了能够基于业务的扩缩容自动的进行采集,就一定少不了服务发现的能力,比如K8s中天然就有这个服务发现的优势。而Push就不需要提前知晓目标地址列表,相对来说就非常的简单了。
能力对比
能力对比 | PULL | PUSH |
---|---|---|
监控对象存活性 | 简单 | 无法区分 |
数据齐全度计算 | 可行 | 较困难 |
短生命周期(Job,Serverles)实时性高 | 难以适用 | 适用 |
指标获取灵活性 | 固定,方便分享,可按需获取 | 灵活, 被动接受链路中学习 |
正是因为两者的工作原理不一样所以也决定了两者能力的区别。在监控领域监控对象的存活性是非常重要的,pull的时候有明确的目标,所以可以非常简单的判断是拉到空数据还是监控对象出问题了,而且也可以控制拉取的周期。而push的时候 不知道周期是多少,没有收到数据的时候也不知道是因为下线了,还是因为挂掉了。所以这也是为什么Prom一直更倾向Pull的方式而不是Push。
但是在一些短生命周期进程,或者trace这类场景,实时性要求很高,或者压根没有办法提前定义监控对象的如浏览器、移动端这种,就只能通过Push的方式进行上报。所以这也是为什么Opentelemetry推出的架构是Push的方式。
成本对比
成本对比 | Pull | Push |
---|---|---|
资源消耗 | 1. 应用暴露端口方式 低2. Exporter方式 较高 3.占用端口资源 | 1.应用推送 消耗低2. Agent推送 消耗低 |
安全性保证 | 工作量大,暴露端口的安全性 | 工作量低 |
核心运维消耗 | 1.平台维护的组件多,成本高2.定位简单 | 1.平台维护的组件少,成本低2.定位难 |
最后一个就是成本的区别,现在服务器的性能已经非常高了,企业的安全保障也相对完善,所以资源消耗和安全性考虑相对可以忽略了。而在实际的生产过程中,其实Push带来的不确定性和扯皮的情况更明显。