diff --git a/img/20210406160656.png b/img/20210406160656.png new file mode 100644 index 0000000..e95dcdd Binary files /dev/null and b/img/20210406160656.png differ diff --git a/img/20210406170536.png b/img/20210406170536.png new file mode 100644 index 0000000..725dd81 Binary files /dev/null and b/img/20210406170536.png differ diff --git a/img/20210406170610.png b/img/20210406170610.png new file mode 100644 index 0000000..8430a75 Binary files /dev/null and b/img/20210406170610.png differ diff --git a/img/20210406180044.png b/img/20210406180044.png new file mode 100644 index 0000000..8c1dfdc Binary files /dev/null and b/img/20210406180044.png differ diff --git a/img/20210408101934.png b/img/20210408101934.png new file mode 100644 index 0000000..55abcea Binary files /dev/null and b/img/20210408101934.png differ diff --git a/img/20210408103734.png b/img/20210408103734.png new file mode 100644 index 0000000..02a73aa Binary files /dev/null and b/img/20210408103734.png differ diff --git a/img/20210408111516.png b/img/20210408111516.png new file mode 100644 index 0000000..9524574 Binary files /dev/null and b/img/20210408111516.png differ diff --git a/img/20210408112246.png b/img/20210408112246.png new file mode 100644 index 0000000..3d274bf Binary files /dev/null and b/img/20210408112246.png differ diff --git a/img/20210408112938.png b/img/20210408112938.png new file mode 100644 index 0000000..bf42ae9 Binary files /dev/null and b/img/20210408112938.png differ diff --git a/img/20210408113024.png b/img/20210408113024.png new file mode 100644 index 0000000..9c562cb Binary files /dev/null and b/img/20210408113024.png differ diff --git a/prometheus/01 基本概念.md b/prometheus/01 基本概念.md new file mode 100644 index 0000000..255b2b2 --- /dev/null +++ b/prometheus/01 基本概念.md @@ -0,0 +1,444 @@ +# 概述 + +[Prometheus](https://prometheus.io/) 是一个监控系统和时序数据库,特别适合监控云原生环境,它具有多维数据模型和强大的查询语言,并在一个生态系统中集成了检测、指标收集、服务发现和报警等功能。 + +本课程将为你从 0 讲解 Prometheus 的基本概念,然后一步一步深入带领你加深对 Prometheus 的理解。 + +## 先决条件 + +本课程的整个演示环境在 CentOS 7.9 上进行测试,但是整个过程基本上不需要很多的改动就可以移植到其他 Linux 发行版中。 + +所以在学习本课程之前你将需要有 Unix/Linux 服务器管理的基础知识,系统监控经验会有所帮助,但并不是必须要的,不需要你具有 Prometheus 本身的经验,因为我们本身就是从 0 开始讲解的,所以你不用担心。 + +## 什么是 Prometheus + +[Prometheus](https://prometheus.io/) 是一个基于指标监控和报警的工具栈。 Prometheus 起源于 SoundCloud ,因为微服务迅速发展,导致实例数量以几何倍数递增,不得不考虑设计一个符合以下几个功能的监控系统: + +- 多维数据模型,可以按照实例,服务,端点和方法之类的维度随意对数据进行切片和切块。 +- 操作简单,可以随时随地部署监控服务,甚至在本地工作站上,而无需设置分布式存储后端或重新配置环境。 +- 可扩展的数据收集和分散的架构,以便于可以可靠的监控服务的许多实例,独立团队可以部署独立的监控服务。 +- 一种查询语言,可以利用数据模型进行有效的报警和图形展示。 + +但是,当时的情况是,以上的功能都分散在各个系统之中,直到 2012 年 SoundCloud 启动了一个孵化项目把这些所有功能集合到一起,也就是 Prometheus。Prometheus 是用 Go 语言编写,从一开始就是开源的,到 2016 年 Prometheus 成为继 Kubernetes 之后,成为 CNCF 的第二个成员。 + +到现在为止 Prometheus 提供的工具或与其他生态系统组件集成可以提供完整的监控管道: + +- 检测(跟踪和暴露指标) +- 指标收集 +- 指标存储 +- 查询指标,用于报警、仪表板等 + +![Prometheus Dashboard](../img/20210406160656.png) + +Prometheus 具有足够的通用性,可以监控各个级别的实例:你自己的应用程序、第三方服务、主机或网络设备等等。此外 Prometheus 特别适用于监控动态云环境和 Kubernetes 云原生环境。 + +但是也需要注意的是 Prometheus 并不是万能的,目前并没有解决下面的一些问题: + +- 日志和追踪(Prometheus 只处理指标,也称为时间序列) +- 基于机器学习或 AI 的异常检测 +- 水平扩展、集群化的存储 + +这些功能显然也是非常有价值的,但是 Prometheus 本身并没有尝试去解决,而是留给了第三方解决方案。 + +但是整体来说与其他监控解决方案相比,Prometheus 提供了许多重要功能: + +- 多维数据模型,允许对指标进行跟踪 +- 强大的查询语言(PromQL) +- 时间序列处理和报警的整合 +- 与服务发现集成来确定应监控的内容 +- 操作简单 +- 执行高效 + +尽管这些功能中的许多功能如今在监控系统中变得越来越普遍,但是 Prometheus 是第一个将所有功能组合在一起的开源解决方案。 + +## 操作简单 + +Prometheus 的整个概念很简单并且操作也非常简单。 Prometheus 用 Go 编写,直接使用独立的二进制文件即可部署,而无需依赖外部运行时(例如 JVM)、解释器(例如 Python 或 Ruby)或共享系统库。 + +每个 Prometheus 服务器都独立于任何其他 Prometheus 服务器收集数据并评估报警规则,并且仅在本地存储数据,而没有严格的集群或副本。 + +要创建用于报警的高可用性配置,你仍然可以运行两个配置相同的 Prometheus 服务器,以计算相同的报警(Alertmanager 将对通知进行去重操作): + +![Prometheus Simple HA](../img/20210406180044.png) + +当然,Prometheus 的大规模部署还是非常复杂的,在后面的章节中接触到,此外 Prometheus 还暴露了一些接口,允许第三方开发者来解决一些问题,比如远程存储这些功能。 + +## 性能高效 + +Prometheus 需要能够同时从许多系统和服务中收集详细的指标数据,为此,特别对以下组件进行了高度优化: + +- 抓取和解析传入的指标 +- 写入和读取时序数据库 +- 评估基于 TSDB 数据的 PromQL 表达式 + +根据社区的使用经验显示,一台大型 Prometheus 服务器每秒可以摄取多达 `100万` 个时间序列样本,并使用 `1-2` 字节来将每个样本存储在磁盘上。 + + + +# 系统架构 + +下图演示了 Prometheus 系统的整体架构。 + +![Prometheus 系统架构](../img/20210406170610.png) + +一个团队通常会运行一个或多个 Prometheus 服务器,这些服务器构成了 Prometheus 监控的核心。Prometheus 服务器可以配置为使用服务发现机制(如 DNS、Consul、Kubernetes 等)来自动发现一组指标源(所谓的`目标`),然后 Prometheus 通过 HTTP 定期从这些目标中以[文本格式](https://prometheus.io/docs/instrumenting/exposition_formats/)`抓取`指标,并将收集到的数据存储在本地时序数据库中。 + +抓取的目标可以是一个直接暴露 Prometheus 指标的应用程序,也是可以是一个将现有系统(比如 MySQL)的 metrics 指标转换为 Prometheus 指标标准格式的中间应用(也就是我们说的 `exporter`),然后 Prometheus 服务器通过其内置的 Web UI、其他仪表盘工具(比如 [Grafana](https://grafana.com/))或者直接使用其 HTTP API 来提供收集到的数据进行查询。 + +> **注意**:每次抓取只会将目标的每个时间序列的当前值传输给 Prometheus,所以抓取间隔决定了存储数据的最终采样频率。目标进程本身不保留任何历史指标数据。 + +另外我们还可以配置 Prometheus 根据收集的指标数据生成报警,但是 Prometheus 不会直接把报警通知发送给我们,而是将原始报警转发到 `Alertmanager` 服务,Alertmanager 是作为单独的服务运行的,可以从多个 Prometheus 服务器上接收报警,并可以对这些报警进行分组、汇总和路由,最后可以通过 Email、Slack、PagerDuty、企业微信、Webhook 或其他通知服务来发送通知。 + + + +# 数据模型 + +Prometheus 采集的监控数据都是以指标(metric)的形式存储在内置的 TSDB 数据库中,这些数据都是**时间序列**:一个带时间戳的数据,这些数据具有一个标识符和一组样本值。除了存储的时间序列,Prometheus 还可以根据查询请求产生临时的、衍生的时间序列作为返回结果。 + + + +## 时间序列 + +Prometheus 会将所有采集到的样本数据以时间序列的形式保存在内存数据库中,并定时刷新到硬盘上,时间序列是按照时间戳和值的序列方式存放的,我们可以称之为**向量**(vector),每一条时间序列都由一个**指标名称**和一组**标签**(键值对)来唯一标识。 + +- 指标名称反映了被监控样本的含义(如 `http_request_total` 表示的是对应服务器处理的 HTTP 请求总数)。 +- 标签可以用来区分不同的维度(比如 `method="GET"` 与 `method="POST"` 就可以用来区分这两种不同的 HTTP 请求指标数据)。 + +如下所示,可以将时间序列理解为一个以时间为 Y 轴的数字矩阵: + +```shell + ^ + │ . . . . . . . . . . . . . . . . . . . http_request_total{method="GET",status="200"} + │ . . . . . . . . . . . . . . . . . . . http_request_total{method="POST",status="500"} + │ . . . . . . . . . . . . . . . . . . + │ . . . . . . . . . . . . . . . . . . + v + <------------------ 时间 ----------------> +``` + + + +需要注意的是指标名称只能由 ASCII 字符、数字、下划线以及冒号组成,同时必须匹配正则表达式 `[a-zA-Z_:][a-zA-Z0-9_:]*`(冒号不能用来定义指标名称,是用来表示用户自定义的记录规则)。标签的名称只能由 ASCII 字符、数字以及下划线组成并满足正则表达式 `[a-zA-Z_][a-zA-Z0-9_]*`,其中以 `__` 作为前缀的标签,是系统保留的关键字,只能在系统内部使用,标签的值则可以包含任何 Unicode 编码的字符。 + + + + + +## 样本 + +时间序列中的每一个点就称为一个样本(sample),样本由以下 3 个部分组成: + +- **指标**:指标名称和描述当前样本特征的标签集 +- **时间戳**:精确到毫秒的时间戳数 +- **样本值**:一个 64 位浮点数 + + + +## 指标 + +想要暴露 Prometheus 指标服务只需要暴露一个 HTTP 端点,并提供 Prometheus 基于文本格式的指标数据即可。这种指标格式是非常友好的,基本上的格式看起来类似于下面的这段代码: + +```txt +# HELP http_requests_total The total number of processed HTTP requests. +# TYPE http_requests_total counter +http_requests_total{status="200"} 8556 +http_requests_total{status="404"} 20 +http_requests_total{status="500"} 68 +``` + + + +其中 `#` 开头的行是注释信息,用来描述下面提供的指标含义,其他未注释行代表一个样本(带有指标名、标签和样本值),使其非常容易从系统和服务中暴露指标出来。 + +事实上所有的指标也都是通过如下所示的格式来标识的: + +```shell +{