Kubernetes + Prometheus监控体系之 - Exporter源码初探(以RedisExporter为例)

Kubernetes集群监控之Prometheus监控方案

如果说Kubernetes是事实上的容器平台标准,那么Prometheus就是云原生监控领域事实上的标准了。Kubernetes + Prometheus的组合自然就成了云原生基础设施的标准搭配。
下图是Kubernetes + Prometheus的通用监控方案
Prometheus监控方案

方案简介

此方案涉及如下几个重要的角色:

  • Prometheus Server
  • Exporter
  • Alert Manager
  • Grafana
  • Kubernetes API Server
  • DB,MiddleWare, Spring Application

Prometheus Server

Prometheus的核心,Prometheus Server 主要由以下几个组件组成:

  1. 数据存储(Storage):Prometheus 使用自己的时间序列数据库来存储采集的指标数据。这个数据库被设计成高效、快速、稳定,并且能够处理大规模的指标数据。

  2. 抓取器(Scraper):抓取器负责定期从各种数据源(如应用程序、操作系统、服务等)中抓取指标数据,并将其存储到时间序列数据库中。Prometheus 支持多种抓取方式,包括 HTTP 抓取、PushGateway 推送、服务发现等。

  3. 查询引擎(Query Engine):查询引擎负责处理用户发起的查询请求,并从时间序列数据库中检索和处理指标数据。Prometheus 使用自己的查询语言 PromQL 来进行查询和分析操作,支持丰富的函数和操作符,能够满足各种复杂的查询需求。

  4. Web 服务器(Web Server):Prometheus Server 包含一个内置的 Web 服务器,用于提供用户界面和 HTTP API。用户可以通过 Web 界面或 API 来查看监控指标、执行查询、设置告警规则等操作。

这些组件共同构成了 Prometheus Server 的核心功能。一般来讲,整体的监控流程如下:

  • 定义一个抓取任务
  • 访问任务中定义的Exporter抓取监控指标数据
  • 将指标数据存储在内部的时序数据库中
  • 通过HTTP API执行查询,以及设置告警规则等
  • 由查询引擎负责处理用户的查询请求

各种Exporter

Exporter 是一种用于从各种系统和服务中抓取指标数据并暴露给 Prometheus 进行监控的软件组件或工具。Exporter主要完成以下几件事情:

  • 连接到指定的服务器,或组件
  • 抓取指定的监控指标
  • 通过HTTP服务将指标数据暴露给Prometheus Server

常用的Exporter有 Node Exporter, JMX Exporter, Redis Exporter, MySQL Exporter, Kubernetes State Metrics Exporter等等。想要知道更多的Exporter可以查看Prometheus官方Exporter 列表:

  • 【Prometheus Exporter List】。

需要说明的是,有一些Exporter需要和被监控的对象部署在一起,而有一些则不需要,例如NodeExporter就是部署在需要被监控的Node节点上,用于采集当前节点的系统监控指标数据。
RedisExporter则可以独立部署,不需要和Redis集群部署在一起,这也是通常的做法。

AlertManager

Prometheus 中的 Alertmanager 是一个用于处理和管理告警的组件。它主要负责以下几个重要的事情:

  1. 告警路由和分组:Alertmanager 负责根据配置的路由规则将接收到的告警分配给相应的接收者。路由规则可以基于告警的标签匹配条件来定义,以确保告警能够被发送到正确的接收者。

  2. 告警去重和抑制:Alertmanager 会对接收到的告警进行去重和抑制,以避免发送重复的告警和避免告警风暴。它可以根据配置的策略对相同的告警进行合并或者抑制一段时间,从而减少告警的数量和频率。

  3. 告警通知:Alertmanager 负责将处理过的告警发送给配置的接收者,如电子邮件、Slack、PagerDuty 等。它支持多种通知方式,并且可以根据告警的严重程度和优先级进行灵活的配置和调整。

  4. 告警静默:Alertmanager 支持对指定的告警规则进行静默,即在一段时间内暂时禁止发送某个规则产生的告警通知。这对于临时性的维护和问题排查非常有用。

Grafana

Grafana 是一个开源的数据可视化和监控平台,主要用于展示和分析各种数据源的监控数据。它提供了丰富的图表和面板,可以直观地展示时间序列数据、日志数据、指标数据。
Grafana 提供了丰富的Dashboard,大家可以去官方查找和下载。

  • 【Grafana Dashboards】

Redis Dashboard

Redis Exporter 源码初探

Redis Exporter 源码下载

我们可以在Github上下载Redis Exporter源码

  • 【Redis Exporter Github Repo】

打开Bash终端,并在终端执行git clone指令:

git clone git@github.com:oliver006/redis_exporter.git

结果如下:

vian@txzq1899-ubuntu:~/ws/redis-exporter$ git clone git@github.com:oliver006/redis_exporter.git
正克隆到 'redis_exporter'...
remote: Enumerating objects: 3882, done.
remote: Counting objects: 100% (891/891), done.
remote: Compressing objects: 100% (317/317), done.
remote: Total 3882 (delta 684), reused 589 (delta 572), pack-reused 2991
接收对象中: 100% (3882/3882), 7.61 MiB | 1.07 MiB/s, 完成.
处理 delta 中: 100% (2156/2156), 完成.
vian@txzq1899-ubuntu:~/ws/redis-exporter$ ll
总计 12
drwxrwxr-x  3 vian vian 4096  512 18:30 ./
drwxrwxr-x 11 vian vian 4096  512 18:29 ../
drwxrwxr-x  7 vian vian 4096  512 18:30 redis_exporter/

使用Visual Studio Code打开 Redis_Exporter 项目

Redis Exporter 是一个Go语言应用程序,所以我们需要在本机安装Go语言环境,我们需要安装两个必备依赖:

  • 最新版本的Go语言
  • Visual Studio Code Go 语言插件

>>>Go 语言安装
可参考官方指引,安装步骤很简单:

  • 【Go语言下载与安装】

【Step 1】下载go语言安装包
在Bash终端执行如下指令

wget https://go.dev/dl/go1.22.3.linux-amd64.tar.gz

等待建立连接和下载

vian@txzq1899-ubuntu:~/ws$ wget https://go.dev/dl/go1.22.3.linux-amd64.tar.gz
--2024-05-12 18:47:10--  https://go.dev/dl/go1.22.3.linux-amd64.tar.gz
正在解析主机 go.dev (go.dev)... 216.239.38.21, 216.239.34.21, 216.239.32.21, ...
正在连接 go.dev (go.dev)|216.239.38.21|:443... 已连接。
已发出 HTTP 请求,正在等待回应... 302 Found
位置:https://dl.google.com/go/go1.22.3.linux-amd64.tar.gz [跟随至新的 URL]
--2024-05-12 18:47:11--  https://dl.google.com/go/go1.22.3.linux-amd64.tar.gz
正在解析主机 dl.google.com (dl.google.com)... 114.250.70.33
正在连接 dl.google.com (dl.google.com)|114.250.70.33|:443... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度: 68958945 (66M) [application/x-gzip]
正在保存至: ‘go1.22.3.linux-amd64.tar.gz’

go1.22.3.linux-amd64.tar.gz           100%[=======================================================================>]  65.76M  5.79MB/s    用时 13s   

2024-05-12 18:47:24 (4.98 MB/s) - 已保存 ‘go1.22.3.linux-amd64.tar.gz’ [68958945/68958945])

【Step 2】解压缩
在Bash终端执行如下命令,这条命令首先会删除原先已经安装的go环境,然后将最新版的go语言安装至/usr/local/go目录下。

 rm -rf /usr/local/go && tar -C /usr/local -xzf go1.22.3.linux-amd64.tar.gz

【Step 3】配置GO PATH
修改**~/.profile**文件,将go语言加入到PATH中

export PATH=$PATH:/usr/local/go/bin

【Step 4】查看Go 版本

vian@txzq1899-ubuntu:~/ws$ go version
go version go1.22.3 linux/amd64

>>>安装VisualStudioCode GO 语言插件
点击“扩展”(Ctrl+Shift+X),搜索"Go",第一个:Go Team at Google ☆ go.dev
Visual Studio Code Go 插件


>>>打开Redis_Exporter项目
当前两步准备就绪后,我们就可以使用Visual Studio Code方便的阅读Redis_Exporter的源码了,打开Redis_Exporter的源码文件夹后,如下图所示:Redis-Exporter-Project


Redis Exporter 项目概览

我们先看根目录:

  • Docker
    • Dockerfile:用于构建RedisExporter镜像
  • Exporter
    • Exporter的实现细节
  • go.mod:Go 模块的依赖管理
  • go.sum:Go 模块的依赖管理
  • main.go:RedisExporter 入口程序
  • Makefile:RedisExporter 构建文件

Redis_Exporter主口程序main.go解读

main()函数
main函数从上往下,主要是做了以下事情

  1. 命令行参数解析:

    • 使用 flag 包解析各种命令行参数,涵盖了 Redis 连接信息、监控配置、日志格式、TLS 加密等方面。
  2. 日志配置:

    • 根据 logFormat 参数设置日志输出格式(文本或 JSON)。
    • 处理 showVersion 参数,如果为 true 则打印版本信息后退出程序。
    • 设置日志输出级别(调试或信息)。
  3. 连接超时解析:

    • 解析 connectionTimeout 参数,将其转换为时间间隔类型 (time.Duration)。
  4. 密码处理:

    • 如果 redisPwd 为空且 redisPwdFile 不为空,则从指定文件中读取密码。
  5. Lua 脚本加载:

    • 如果 scriptPath 不为空,则依次加载指定路径的 Lua 脚本。
  6. 指标注册:

    • 创建 prometheus 注册器,用于收集和注册监控指标。
    • 根据 redisMetricsOnly 参数决定是使用单独的注册器还是默认注册器。
  7. ☆☆☆Redis 连接器创建:☆☆☆

    • 创建 exporter.NewRedisExporter 对象,用于连接 Redis 并收集监控数据。
    • 将解析到的配置信息作为参数传入构造函数。
exp, err := exporter.NewRedisExporter(
		*redisAddr,
		exporter.Options{}
  1. TLS 配置验证:

    • 检查客户端证书和密钥文件是否成对出现。
    • 创建客户端 TLS 配置并进行验证。
  2. ☆☆☆启动 web 服务:☆☆☆

    • 打印提供监控指标的地址信息。
    • 创建 http.Server 对象,用于监听指定端口并处理客户端请求。
    • 根据 tlsServerCertFiletlsServerKeyFile 参数判断是否启用 TLS 加密。
    • 启动 goroutine 运行 web 服务。
      • go func() {

        server.ListenAndServe()

        }()
server := &http.Server{
		Addr:    *listenAddress,
		Handler: exp,
	}

go func() {
		if *tlsServerCertFile != "" && *tlsServerKeyFile != "" {
			...
			if err := server.ListenAndServeTLS("", ""); err != nil && !errors.Is(err, http.ErrServerClosed) {
				log.Fatalf("TLS Server error: %v", err)
			}
		} else {
			if err := server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
				log.Fatalf("Server error: %v", err)
			}
		}
	}()
  1. 优雅退出:
  • 创建信号通道 quit ,用于接收终止信号 (SIGINT, SIGTERM)。
  • 监听信号并捕获第一个收到的信号。
  • 创建带超时的 context,用于控制服务优雅关闭的时间。
  • 根据 context 关闭 web 服务。

exporter.go解读

  • 定义了Exporter结构体
  • 定义了Options结构体
  • 定义Redis监控指标的Exporter
    • func NewRedisExporter(redisURI string, opts Options) (*Exporter, error)
  • 实现了prometheus.Exporter接口
    • 实现了Collect()方法和Describe()方法
    • Collect()方法会调用scrapeRedisHost()方法抓取监控指标
      Exporter 整体结构
      接口定义请查看prometheus collector源码:
      home/vian/go/pkg/mod/github.com/prometheus/client_golang@v1.19.1/prometheus/collector.go
      在这里插入图片描述

Exporter 结构体解读

// Exporter implements the prometheus.Exporter interface, and exports Redis metrics.
type Exporter struct {
	sync.Mutex

	redisAddr string
	namespace string

	totalScrapes              prometheus.Counter
	scrapeDuration            prometheus.Summary
	targetScrapeRequestErrors prometheus.Counter

	//指标描述
	metricDescriptions map[string]*prometheus.Desc

	options Options

	//累计形指标
	metricMapCounters map[string]string
	//即时指标
	metricMapGauges   map[string]string

	//http多路复用器,用于处理http请求
	mux *http.ServeMux

	buildInfo BuildInfo
}

NewRedisExporter函数解读

  • 【Part1】Exporter的初始化(含指标定义)
    Exporter的初始化
    所有的Redis指标,均在NewRedisExporter中初始化Exporter时定义,从114行至301行:
	//累计形指标的详细定义
	metricMapCounters map[string]string
	//即时指标的详细定义 
	metricMapGauges   map[string]string
  • 【Part2】Exporter 的WEB 服务设置
    • 定义监听哪些HTTP请求的URI,以及对应的HTTP Handler

      • /
      • /metrics
      • /scrape
      • /health
      • /-/reload
      	......
      	if e.options.MetricsPath == "" {
      		e.options.MetricsPath = "/metrics"
      	}
      
      	e.mux = http.NewServeMux()
      
      	if e.options.Registry != nil {
      		e.options.Registry.MustRegister(e)
      		//这里用于定义/metrics的HTTP Handler
      		//promhttp.HandlerFor返回一个HTTP Handler
      		e.mux.Handle(e.options.MetricsPath, promhttp.HandlerFor(
      			e.options.Registry, promhttp.HandlerOpts{ErrorHandling: promhttp.ContinueOnError},
      		))
      		......
      		}
      	}
      
      	e.mux.HandleFunc("/", e.indexHandler)
      	e.mux.HandleFunc("/scrape", e.scrapeHandler)
      	e.mux.HandleFunc("/health", e.healthHandler)
      	e.mux.HandleFunc("/-/reload", e.reloadPwdFile)
      
  • 【Part3】promhttp.HandlerFor 源码解读
    源码路径:
    /home/vian/go/pkg/mod/github.com/prometheus/client_golang@v1.19.1/prometheus/promhttp/http.go
    • HandlerFor()方法
    func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler {
    	return HandlerForTransactional(prometheus.ToTransactionalGatherer(reg), opts)
    }
    
    • HandlerForTransactional()方法
      • 调用reg.Gather()方法
      • 这里的register就是Exporter.Options.Register
        在这里插入图片描述
      • Register 实现 Gather接口 源码: /home/vian/go/pkg/mod/github.com/prometheus/client_golang@v1.19.1/prometheus/registry.go
      • 调用Collect方法()
        最终调用Exporter中的Collect方法
        调用collect方法
        代码跟到这里,指标采集的链路就形成了闭环。从Part3开始就是Prometheus的实现了,RedisExporter只需要实现相应的接口即可。

总结

当然Redis Exporter还有很多实现细节等着我们去探索,本文仅仅只是把Exporter的大致路径摸索了一下,刚刚找到入口,具体的细节还需要我们进一步的去探究。希望感兴趣的朋友一起交流和探索。

关注我的公众号

欢迎大家关注、点赞、转发,一起交流软件开发、架构设计、云原生技术。
TXZQ聊IT技术与架构

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/619956.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python版Spark core详解

文章目录 第一章 SparkCore1.1. Spark环境部署1.1.1. Spark介绍1.1.1.1. 什么是Spark1.1.1.2. Spark与MapReduce的对比框架对比运行流程对比 1.1.1.3. Spark的组件1.1.1.4. Spark的特点 1.1.2. Spark的安装部署1.1.2.1. Spark安装包下载1.1.2.2. Spark部署模式介绍1.1.2.3. Loc…

Excel 同一分类下进行跨行计算

例题描述 Excel 文件记录不同用户的事件发生时间,数据已按 USER ID 和 DATE 列排序,部分数据如下: ABC1USER IDEVENT IDDATE2142020-01-013152020-01-054162020-01-135272020-01-036282020-01-057292020-01-06 现在要计算事件真假列isTrue&…

Ansys ACT的一个例子

由XML和IronPython文件组成&#xff0c;文件结构如下&#xff1a; ExtSample.xml <extension version"1" name"ExtSample1"><guid shortid"ExtSample1">2cc739d5-9011-400f-ab31-a59e36e5c595</guid><script src"sam…

极度内卷,消费下行,AIGC如何成为普通人易变现好上手的新机会,这几种方法一定要尝试!

最近看到一个麦肯锡报告&#xff0c;说到2030年&#xff0c;AI会替代1亿多中国人的岗位。 暂且不说这个预测是否准确&#xff0c;但自从AI横空出世&#xff0c;确实给我们的生活带来了翻天覆地的变化&#xff0c;有人顺势起飞&#xff0c;有人被时代淘汰… 李开复也曾不止一次…

无人售货机零售项目ECharts展现(最全!!,文档放最后哦!)

目录 背景 数据表 框架分析 可视化展示销售情况总分析 1、绘制仪表盘展示各特征及其环比增长率&#xff08;仪表盘&#xff09; 1. 销售金额及其环比增长率 2. 订单量及其环比增长率 3. 毛利率及其环比增长率 4.售货机数量及其环比增长率 2、绘制簇状柱状-折线图展示…

视频创作提效绘唐3漫剪使用教程

只需要提取视频内容&#xff0c;自动帮您修改对应文案&#xff0c;修改率高达70%&#xff0c;语句流畅度高达80%&#xff0c;只需稍微进行修稿&#xff0c;马上完成原创作品工具入口 原文&#xff1a;这个世界的鬼&#xff0c;成年后都要来人间找工作 改文&#xff1a;这个世界…

【linux学习】多线程(1)

文章目录 线程的概念线程与进程 线程的用法线程的创建多线程 线程的等待线程锁死锁 线程的概念 在Linux中&#xff0c;线程&#xff08;Thread&#xff09;是程序执行流的最小单位&#xff0c;是进程中的一个实体&#xff0c;负责在程序中执行代码。线程本身不拥有系统资源&…

flink尚硅谷

flink 1 flink基础使用1.1 角色1.2 部署模式&#xff08;抽象&#xff09;1.2.1 会话模式1.2.2 单作业模式1.2.3 应用模式 1.3 运行模式&#xff08;实际 谁来管理资源&#xff09;1.3.1 Stand alone1.3.2 YARN运行模式&#xff08;重点&#xff09; 2. 运行时架构2.1 系统架构…

windows 10安装 docker desktop

升级 windows 10 windows 10 升级到 20H2&#xff0c;如 20H2 19045.4291。 注意&#xff1a;需返回更新&#xff0c;重启计算机&#xff0c;确保更新完整。 bios 开启虚拟化 开启cpu虚拟化功能。 windows 启用功能 启用hyper-v 启用 wsl 安装 wsl https://learn.microso…

锁策略详解:互斥锁、读写锁、乐观锁与悲观锁、轻量级锁与重量级锁、自旋锁、偏向锁、可重入锁与不可重入锁、公平锁与非公平锁

一.锁策略 锁策略指的是在多线程编程中用于管理共享资源访问的规则和技术。它们确保在任何给定时间只有一个线程可以访问共享资源&#xff0c;以防止竞态条件和数据不一致性问题。常见的锁策略包括&#xff1a; 互斥锁&#xff08;Mutex&#xff09;&#xff1a;最常见的锁类型…

导航app为什么知道还有几秒变绿灯?

在使用地图导航app行驶至信号灯的交叉路口时&#xff0c;这些应用程序会贴心地告知用户距信号灯变化还有多少秒&#xff0c;无论是即将转为绿灯还是红灯。这一智能化提示不仅使得驾驶员能适时做好起步或刹车的准备&#xff0c;有效缓解了因等待时间不确定而产生的焦虑情绪&…

活动预告|“AI+Security”系列第1期:大模型网络空间安全前沿探索活动火热报名中

由Wisemodel社区、安全极客主办的 “AISecurity”系列第1期&#xff1a; 大模型网络空间安全前沿探索 线下活动 将于2024年5月18日下午14:00 在苏州街16号神州数码大厦5层举行 本活动旨在汇聚业界专家和实践者共同探讨和推进AI自身安全、AI赋能安全与AI给安全带来的挑战等关…

Blender动画与云渲染:创造高质量作品的未来路径

Blender作为开源的3D图形软件&#xff0c;在多个领域广受欢迎。但随着项目复杂度提升&#xff0c;传统渲染方式受限。云渲染技术的兴起突破了这些限制&#xff0c;为创作者提供了更自由、高效的创作环境。 一、Blender动画项目的挑战 传统上&#xff0c;Blender动画渲染需要依…

【C语言】深度解析:动态内存管理的机制与实践

&#x1f525;引言 本篇将深度解析:动态内存管理的机制。为了更加灵活分配内存中的空间&#xff0c;库中为了我们提供了一些的函数&#xff0c;去动态开辟和释放堆上的空间。 &#x1f308;个人主页&#xff1a;是店小二呀 &#x1f308;C语言笔记专栏&#xff1a;C语言笔记 &a…

【Redis】Redis入门概述

&#x1f600;大家好&#xff0c;我是白晨&#xff0c;一个不是很能熬夜&#x1f62b;&#xff0c;但是也想日更的人✈。如果喜欢这篇文章&#xff0c;点个赞&#x1f44d;&#xff0c;关注一下&#x1f440;白晨吧&#xff01;你的支持就是我最大的动力&#xff01;&#x1f4…

选择数据摆渡系统 哪个厂家比较好?

数据摆渡系统是一种用于在不同网络或安全域之间安全传输数据的技术解决方案。它通常用于解决网络隔离环境下的数据交换问题&#xff0c;确保数据在传输过程中的安全性、完整性和合规性。数据摆渡系统可以采用物理手段&#xff0c;如通过专用隔离硬件和私有安全协议&#xff0c;…

数据结构的二叉树(c语言版)

一.二叉树的概念 1.二叉树的基本概念 二叉树是一种常见的树状数据结构&#xff0c;它由若干个节点组成&#xff0c;这些节点通过边连接起来。每个节点最多可以有两个子节点&#xff0c;分别称为左子节点和右子节点。 二叉树的特点是每个节点最多有两个子节点&#xff0c;而且…

上海市青少年算法2023年12月月赛(丙组)试题解析

上海市青少年算法2023年12月月赛(丙组)试题解析 T1数砖数 题目描述 给定一种 22 规格的瓷砖,该瓷砖的式样为 ## .# 用这种瓷砖,从平面的左上角出发,将整个平面铺满,形如: 给定两个整数 n 与 m,请计算从左上角开始的 n 行 m 列的区域中,有多少格子是 #。 输入格式 第一…

易百纳与成都鼎桥达成战略合作,共创海鸥派生态新篇章

前言 易百纳技术社区&#xff08;以下简称“易百纳”&#xff09;与成都鼎桥通信技术有限公司&#xff08;以下简称“成都鼎桥”&#xff09;达成共建海鸥派的周边生态战略合作。基于海鸥派推出的鼎桥TD OS嵌入式发行版1.0&#xff0c;为海鸥派生态注入新的活力。 易百纳 Eba…

机器人增量学习研究综述

源自&#xff1a;控制与决策 作者&#xff1a;马旭淼 徐德 “人工智能技术与咨询” 发布 摘 要 机器人的应用场景正在不断更新换代,数据量也在日益增长.传统的机器学习方法难以适应动态的环境,而增量学习技术能够模拟人类的学习过程,使机器人能利用旧知识来加快新任务的…