通过学习这些关键的术语和概念来理解 Python 应用监测。

当我***次看到术语“计数器counter”和“计量器gauge”和使用颜色及标记着“平均数”和“大于 90%”的数字图表时,我的反应之一是逃避。就像我看到它们一样,我并不感兴趣,因为我不理解它们是干什么的或如何去使用。因为我的工作不需要我去注意它们,它们被我完全无视。

这都是在两年以前的事了。随着我的职业发展,我希望去了解更多关于我们的网络应用程序的知识,而那个时候就是我开始去学习监测指标metrics的时候。

我的理解监测的学习之旅共有三个阶段(到目前为止),它们是:

阶段 1:什么?(王顾左右)

阶段 2:没有指标,我们真的是瞎撞。

阶段 3:出现不合理的指标我们该如何做?

我现在处于阶段 2,我将分享到目前为止我学到了些什么。我正在向阶段 3 进发,在本文结束的位置我提供了一些我正在使用的学习资源。

我们开始吧!

需要的软件

在文章中讨论时用到的 demo 都可以在 我的 GitHub 仓库 中找到。你需要安装 docker 和 docker-compose 才能使用它们。

为什么要监测?

关于监测的主要原因是:

理解 正常的 和 不正常的 系统和服务的特征

做容量规划、弹性伸缩

有助于排错

了解软件/硬件改变的效果

测量响应中的系统行为变化

当系统出现意外行为时发出警报

指标和指标类型

从我们的用途来看,一个指标就是在一个给定时间点上的某些数量的 测量 值。博客文章的总点击次数、参与讨论的总人数、在缓存系统中数据没有被找到的次数、你的网站上的已登录用户数 —— 这些都是指标的例子。

它们总体上可以分为三类:

计数器

以你的个人博客为例。你发布一篇文章后,过一段时间后,你希望去了解有多少点击量,这是一个只会增加的数字。这就是一个计数器counter指标。在你的博客文章的生命周期中,它的值从 0 开始增加。用图表来表示,一个计数器看起来应该像下面的这样:

一个计数器指标总是在增加的。

计量器

如果你想去跟踪你的博客每天或每周的点击量,而不是基于时间的总点击量。这种指标被称为一个计量器gauge,它的值可上可下。用图表来表示,一个计量器看起来应该像下面的样子:

一个计量器指标可以增加或减少。

一个计量器的值在某些时间窗口内通常有一个***值ceiling和

柱状图和计时器

柱状图histogram(在 Prometheus 中这么叫它)或计时器timer(在 StatsD 中这么叫它)是一个跟踪 已采样的观测结果 的指标。不像一个计数器类或计量器类指标,柱状图指标的值并不是显示为上或下的样式。我知道这可能并没有太多的意义,并且可能和一个计量器图看上去没有什么不同。它们的不同之处在于,你期望使用柱状图数据来做什么,而不是与一个计量器图做比较。因此,监测系统需要知道那个指标是一个柱状图类型,它允许你去做哪些事情。

一个柱状图指标可以增加或减少。

Demo 1:计算和报告指标

Demo 1 是使用 Flask 框架写的一个基本的 web 应用程序。它演示了我们如何去 计算 和 报告 指标。

在 src 目录中有 app.py 和 src/helpers/middleware.py 应用程序,包含以下内容:

fromflaskimportrequest

importcsv

importtime

defstart_timer():

request.start_time=time.time()

defstop_timer(response):

#convertthisinto millisecondsforstatsd

resp_time=(time.time()-request.start_time)*1000

withopen('metrics.csv','a',newline='')asf:

csvwriter=csv.writer(f)

csvwriter.writerow([str(int(time.time())),str(resp_time)])

returnresponse

defsetup_metrics(app):

app.before_request(start_timer)

app.after_request(stop_timer)

当在应用程序中调用 setup_metrics() 时,它配置在一个请求被处理之前调用 start_timer() 函数,然后在该请求处理之后、响应发送之前调用 stop_timer() 函数。在上面的函数中,我们写了时间戳并用它来计算处理请求所花费的时间。

当我们在 demo1 目录中运行 docker-compose up,它会启动这个 web 应用程序,然后在一个客户端容器中可以生成一些对 web 应用程序的请求。你将会看到创建了一个 src/metrics.csv 文件,它有两个字段:timestamp 和 request_latency。

通过查看这个文件,我们可以推断出两件事情:

生成了很多数据

没有观测到任何与指标相关的特征

没有观测到与指标相关的特征,我们就不能说这个指标与哪个 HTTP 端点有关联,或这个指标是由哪个应用程序的节点所生成的。因此,我们需要使用合适的元数据去限定每个观测指标。

《Statistics 101》

(LCTT 译注:这是一本统计学入门教材的名字)

假如我们回到高中数学,我们应该回忆起一些统计术语,虽然不太确定,但应该包括平均数、中位数、百分位和柱状图。我们来简要地回顾一下它们,不用去管它们的用法,就像是在上高中一样。

平均数

平均数mean,即一系列数字的平均值,是将数字汇总然后除以列表的个数。3、2 和 10 的平均数是 (3+2+10)/3 = 5。

中位数

中位数median是另一种类型的平均,但它的计算方式不同;它是列表从小到大排序(反之亦然)后取列表的中间数字。以我们上面的列表中(2、3、10),中位数是 3。计算并不是非常直观,它取决于列表中数字的个数。

百分位

百分位percentile是指那个百(千)分比数字低于我们给定的百分数的程度。在一些场景中,它是指这个测量值低于我们数据的百(千)分比数字的程度。比如,上面列表中 95% 是 9.29999。百分位的测量范围是 0 到 100(不包括)。0% 是一组数字的最小分数。你可能会想到它的中位数是 50%,它的结果是 3。

一些监测系统将百分位称为 upper_X,其中 X 就是百分位;upper 90 指的是在 90% 的位置的值。

分位数

“q-分位数”是将有 N 个数的集合等分为 qN 级。q 的取值范围为 0 到 1(全部都包括)。当 q 取值为 0.5 时,值就是中位数。(分位数quantile)和百分位数的关系是,分位数值 q 等于 100 百分位值。

柱状图

Histogram graph

累积柱状图

一个累积柱状图cumulative histogram也是一个柱状图,它的每个桶的数包含前一个桶的数,因此命名为累积。将上面的数据集做成累积柱状图后,看起来应该是这样的:

Cumulative histogram

我们为什么需要做统计?

在上面的 Demo 1 中,我们注意到在我们报告指标时,这里生成了许多数据。当我们将它们用于指标时我们需要做统计,因为它们实在是太多了。我们需要的是整体行为,我们没法去处理单个值。我们预期展现出来的值的行为应该是代表我们观察的系统的行为。

Demo 2:在指标上增加特征

在我们上面的的 Demo 1 应用程序中,当我们计算和报告一个请求的延迟时,它指向了一个由一些特征 唯一标识的特定请求。下面是其中一些:

HTTP 端点

HTTP 方法

运行它的主机/节点的标识符

如果我们将这些特征附加到要观察的指标上,每个指标将有更多的内容。我们来解释一下 Demo 2 中添加到我们的指标上的特征。

在写入指标时,src/helpers/middleware.py 文件将在 CSV 文件中写入多个列:

node_ids=['10.0.1.1','10.1.3.4']

defstart_timer():

request.start_time=time.time()

defstop_timer(response):

#convertthisinto millisecondsforstatsd

resp_time=(time.time()-request.start_time)*1000

node_id=node_ids[random.choice(range(len(node_ids)))]

withopen('metrics.csv','a',newline='')asf:

csvwriter=csv.writer(f)

csvwriter.writerow([

str(int(time.time())),'webapp1',node_id,

request.endpoint,request.method,str(response.status_code),

str(resp_time)

])

returnresponse

因为这只是一个演示,在报告指标时,我们将随意的报告一些随机 IP 作为节点的 ID。当我们在 demo2 目录下运行 docker-compose up 时,我们的结果将是一个有多个列的 CSV 文件。

用 pandas 分析指标

我们将使用 pandas 去分析这个 CSV 文件。运行 docker-compose up 将打印出一个 URL,我们将使用它来打开一个 Jupyter 会话。一旦我们上传 Analysis.ipynb notebook 到会话中,我们就可以将 CSV 文件读入到一个 pandas 数据帧DataFrame中:

importpandasaspd

metrics=pd.read_csv('/data/metrics.csv',index_col=0)

index_col 表明我们要指定时间戳作为索引。

因为每个特征我们都要在数据帧中添加一个列,因此我们可以基于这些列进行分组和聚合:

importnumpyasnp

metrics.groupby(['node_id','http_status']).latency.aggregate(np.percentile,99.999)

更多内容请参考 Jupyter notebook 在数据上的分析示例。

我应该监测什么?

一个软件系统有许多的变量,这些变量的值在它的生命周期中不停地发生变化。软件是运行在某种操作系统上的,而操作系统同时也在不停地变化。在我看来,当某些东西出错时,你所拥有的数据越多越好。

我建议去监测的关键操作系统指标有:

CPU 使用

系统内存使用

文件描述符使用

磁盘使用

还需要监测的其它关键指标根据你的软件应用程序不同而不同。

网络应用程序

如果你的软件是一个监听客户端请求和为它提供服务的网络应用程序,需要测量的关键指标还有:

入站请求数(计数器)

未处理的错误(计数器)

请求延迟(柱状图/计时器)

排队时间,如果在你的应用程序中有队列(柱状图/计时器)

队列大小,如果在你的应用程序中有队列(计量器)

工作进程/线程用量(计量器)

如果你的网络应用程序在一个客户端请求的环境中向其它服务发送请求,那么它应该有一个指标去记录它与那个服务之间的通讯行为。需要监测的关键指标包括请求数、请求延迟、和响应状态。

HTTP web 应用程序后端

HTTP 应用程序应该监测上面所列出的全部指标。除此之外,还应该按 HTTP 状态代码分组监测所有非 200 的 HTTP 状态代码的大致数据。如果你的 web 应用程序有用户注册和登录功能,同时也应该为这个功能设置指标。

长时间运行的进程

长时间运行的进程如 Rabbit MQ 消费者或任务队列的工作进程,虽然它们不是网络服务,它们以选取一个任务并处理它的工作模型来运行。因此,我们应该监测请求的进程数和这些进程的请求延迟。

不管是什么类型的应用程序,都有指标与合适的元数据相关联。

将监测集成到一个 Python 应用程序中

将监测集成到 Python 应用程序中需要涉及到两个组件:

更新你的应用程序去计算和报告指标

配置一个监测基础设施来容纳应用程序的指标,并允许去查询它们

下面是记录和报告指标的基本思路:

defwork():

requests+=1

#report counter

start_time=time.time()

#

#calculateandreport latency

work_latency=time.time()-start_time

...

考虑到上面的模式,我们经常使用修饰符、内容管理器、中间件(对于网络应用程序)所带来的好处去计算和报告指标。在 Demo 1 和 Demo 2 中,我们在一个 Flask 应用程序中使用修饰符。

指标报告时的拉取和推送模型

大体来说,在一个 Python 应用程序中报告指标有两种模式。在 拉取 模型中,监测系统在一个预定义的 HTTP 端点上“刮取”应用程序。在推送 模型中,应用程序发送数据到监测系统。

Pull and push models

工作在 拉取 模型中的监测系统的一个例子是 Prometheus。而 StatsD 是 推送 模型的一个例子。

集成 StatsD

将 StatsD 集成到一个 Python 应用程序中,我们将使用 StatsD Python 客户端,然后更新我们的指标报告部分的代码,调用合适的库去推送数据到 StatsD 中。

首先,我们需要去创建一个客户端实例:

statsd=statsd.StatsClient(host='statsd',port=8125,prefix='webapp1')

prefix 关键字参数将为通过这个客户端报告的所有指标添加一个指定的前缀。

一旦我们有了客户端,我们可以使用如下的代码为一个计时器报告值:

statsd.timing(key,resp_time)

增加计数器:

statsd.incr(key)

将指标关联到元数据上,一个键的定义为:metadata1.metadata2.metric,其中每个 metadataX 是一个可以进行聚合和分组的字段。

这个演示应用程序 StatsD 是将 statsd 与 Python Flask 应用程序集成的一个完整示例。

集成 Prometheus

要使用 Prometheus 监测系统,我们使用 Promethius Python 客户端。我们将首先去创建有关的指标类对象:

REQUEST_LATENCY=Histogram('request_latency_seconds','Request latency',

['app_name','endpoint']

)

在上面的语句中的第三个参数是与这个指标相关的标识符。这些标识符是由与单个指标值相关联的元数据定义的。

去记录一个特定的观测指标:

REQUEST_LATENCY.labels('webapp',request.path).observe(resp_time)

下一步是在我们的应用程序中定义一个 Prometheus 能够刮取的 HTTP 端点。这通常是一个被称为 /metrics 的端点:

@app.route('/metrics')

defmetrics():

returnResponse(prometheus_client.generate_latest(),mimetype=CONTENT_TYPE_LATEST)

这个演示应用程序 Prometheus 是将 prometheus 与 Python Flask 应用程序集成的一个完整示例。

哪个更好:StatsD 还是 Prometheus?

本能地想到的下一个问题便是:我应该使用 StatsD 还是 Prometheus?关于这个主题我写了几篇文章,你可能发现它们对你很有帮助:

指标的使用方式

我们已经学习了一些关于为什么要在我们的应用程序上配置监测的原因,而现在我们来更深入地研究其中的两个用法:报警和自动扩展。

使用指标进行报警

指标的一个关键用途是创建警报。例如,假如过去的五分钟,你的 HTTP 500 的数量持续增加,你可能希望给相关的人发送一封电子邮件或页面提示。对于配置警报做什么取决于我们的监测设置。对于 Prometheus 我们可以使用 Alertmanager,而对于 StatsD,我们使用 Nagios。

使用指标进行自动扩展

在一个云基础设施中,如果我们当前的基础设施供应过量或供应不足,通过指标不仅可以让我们知道,还可以帮我们实现一个自动伸缩的策略。例如,如果在过去的五分钟里,在我们服务器上的工作进程使用率达到 90%,我们可以水平扩展。我们如何去扩展取决于云基础设施。AWS 的自动扩展,缺省情况下,扩展策略是基于系统的 CPU 使用率、网络流量、以及其它因素。然而,让基础设施伸缩的应用程序指标,我们必须发布 自定义的 CloudWatch 指标。

在多服务架构中的应用程序监测

当我们超越一个单应用程序架构时,比如当客户端的请求在响应被发回之前,能够触发调用多个服务,就需要从我们的指标中获取更多的信息。我们需要一个统一的延迟视图指标,这样我们就能够知道响应这个请求时每个服务花费了多少时间。这可以用 分布式跟踪 来实现。

你可以在我的博客文章 《在你的 Python 应用程序中通过 Zipkin 引入分布式跟踪》 中看到在 Python 中进行分布式跟踪的示例。

划重点

总之,你需要记住以下几点:

理解你的监测系统中指标类型的含义

知道监测系统需要的你的数据的测量单位

监测你的应用程序中的大多数关键组件

监测你的应用程序在它的大多数关键阶段的行为

以上要点是假设你不去管理你的监测系统。如果管理你的监测系统是你的工作的一部分,那么你还要考虑更多的问题!

其它资源

以下是我在我的监测学习过程中找到的一些非常有用的资源:

综合的

StatsD/Graphite

Prometheus

避免犯错(即第 3 阶段的学习)

在我们学习监测的基本知识时,时刻注意不要犯错误是很重要的。以下是我偶然发现的一些很有见解的资源:

【责任编辑:庞桂玉 TEL:(010)68476606】

点赞 0

python 监测_理解监测指标,并使用Python去监测它们相关推荐

  1. ai python 面试_面试分享系列 | 17道Python面试题,让你在求职中无往不利

    今天给大家分享的是Python面试题系列的第一篇文章,后续我也会陆续整理Python相关的问题给大家,无论是求职者还是新人都可以通过面试题来考察自己的能力缺陷. 1.Python中pass语句的作用是 ...

  2. 免费学python编程_强力推荐,非常全的 Python编程学习资料(今日免费)

    因为大数据和 AI,Python 一跃成为最火的语言,这里推荐几本畅销排行榜上的好书. 有需要在我的头条号,私信我,"Python",即可免费领取. 一.Python基础教程 &l ...

  3. 请给出计算231-1的python表达式_计算 2 31 -1 的 Python 表达式是 。_学小易找答案

    [填空题]国内教学目标分类的二维层次模型中,教学内容被分为哪五个层次:事实.概念.技能.______.问题解决. [多选题]报表子系统提供的图表格式一般包括? [填空题]激发和维持学生学习动机的模型- ...

  4. 零基础如何入门python语言_零基础如何开始学习 Python

    Python是一门简单优雅的计算机程序设计语言,相比于C语言.Java语言,Python编程具有以下特点: 1. Python语法简单,代码可读性高,容易入门: 2. Python代码具有一定的规范性 ...

  5. flask执行python脚本_如何在Flask中运行python脚本

    我有一个Flask脚本,可以创建网站并动态打印一些数据.-打印的数据应来自另一个python脚本. 我目前面临的问题是,如果我将执行python脚本的行放在执行Flask应用程序的行之前,它将运行Py ...

  6. 苹果系统安装python环境_如何在mac下配置python虚拟环境

    安装python虚拟环境核心目的就是为了复制一个python环境,这样新项目下载的所有包,都会存放在虚拟环境下的python site-package 中 首先安装 1. sudo pip insta ...

  7. 量化投资与python语言_在量化投资领域,为什么Python如此受欢迎?

    说起Web领域 你立马会想到JavaScript语言,它在Web领域不可撼动:Python也已经在金融量化投资领域占据了重要位置,从各个业务链条都能找到相应的框架实现. 在量化投资(证券和比特币)开源 ...

  8. 小猿圈python视频_小猿圈分享学习Python的最佳方式

    原标题:小猿圈分享学习Python的最佳方式 python现在是世界上功能最多的编程语言之一,可以是用Python编辑应用程序,游戏.算法程序.还可以编程一个机器人,学习Python可以担任软件工程师 ...

  9. 下载anaconda前需要卸载python吗_装了anaconda要卸载python吗

    装了anaconda其实是可以选择卸载python,当然也可以不卸载.Anaconda 是Python的一个发行版,里面内置了很多工具,不用单独安装,因为做了优化也免去了单独安装带来的一些麻烦. An ...

最新文章

  1. 腾讯面试官问我Java中boolean类型占用多少个字节?我说一个,面试官让我回家等通知...
  2. 电脑主板维修_自学电脑主板维修第45讲
  3. 个人计算机技术分享,一个计算机类本科毕业设计分享
  4. LIST OF CITIES FOR POTENTIAL VISIT IN SOUTHERN UK
  5. 关于struts2在页面请求转发到action的问题
  6. ElasticSearch 聚合查询
  7. Java中Lambda表达式的使用(转)
  8. Apache 中 .htaccess 文件设置技巧16则
  9. 上拉刷新下拉加载PullToRefreshLayout
  10. 第五章 事务 视图 索引 备份和恢复
  11. csdn下载频道积分规则
  12. 脚本入门(2)-perl脚本
  13. MyBatis mysql 字符串拼接
  14. 基于STM32F103完成对SD卡的数据读取操作
  15. 西门子水处理1200PLC程序+触摸屏程序,博图V16学习程序,可仿真实验 Plc程序包含功能块,功能块为SCL编写
  16. 浅探PWM整流器的开环整流模式
  17. 鸿蒙系统是不是无法注册gmail邮箱也无法正常使用youtube?
  18. Hadoop与MPP
  19. ensp中ap获取不到ip_ensp wlan实验,sta无法获取IP地址?
  20. 如何在Linux中发现IP地址冲突

热门文章

  1. KBEngine demo搭建流程
  2. Unity-协程详解
  3. 合适的线程数量是多少?CPU 核心数和线程数的关系?
  4. JAVA-JDBC原理
  5. 修改Android 自带输入法(LatinIME)空格键的显示
  6. Java学习------第一周知识点总结
  7. python格式化操作符
  8. 和平精英体验服要维护服务器,和平精英体验服关服维护要多久?和平精英体验服开放时间一览[多图]...
  9. 江苏省2021年计算机二级考试成绩,2021年江苏省计算机等级考试分数公布时间|成绩查询入口...
  10. 基于MATLAB的GUI界面数字图像处理系统