当前位置: 首页 > 科技观察

Prometheus插桩应用的使用方法

时间:2023-03-13 19:19:37 科技观察

我们已经知道如何将应用监控指标接入Prometheus,但是如何在自己的应用中暴露监控指标呢?我们可以直接在应用中集成metrics指标数据,也可以自己开发相应的exporter单独暴露指标,或者写脚本推送到pushgateway根据需求生成监控指标,但是最好的方式是直接集成Prometheus监控指标应用程序中的数据。接下来,我们将学习如何使用Prometheus客户端库暴露监控指标,使用PrometheusGo客户端库对Go应用进行插桩,并在代码中直接添加相关指标以获得应用的监控能力。抓取指标我们已经看到了Prometheus是如何抓取监控指标的。Prometheus通过HTTP请求捕获监控目标。请求的默认端点名称是/metrics。监控目标通过发送每个跟踪时间序列的单个样本以及样本的指标名称、标签集和样本值来响应每个指标的当前状态。获取数据后,Prometheus存储每个样本并为其添加服务器端时间戳,从而从一次获取中构建一组时间序列。此外我们再回顾下获取的监控指标格式:#HELPhttp_requests_totalThetotalnumberofHTTPrequests.#TYPEhttp_requests_totalcounterhttp_requests_total{method="post",code="200"}1027http_requests_total{method="post",code="400"}3#HELPprocess_open_fdsNumberofopenfiledescriptors.#TYPEprocess_open_fdsgaugeprocess_open_fds15#HELPhttp_request_duration_secondsAhistogramoftherequestduration.#TYPEhttp_request_duration_secondshistogramhttp_request_duration_seconds_bucket{le="0.05"}24054http_request_duration_seconds_bucket{le="0.1"}33444http_request_duration_seconds_bucket{le="0.2"}100392http_request_duration_seconds_bucket{le="0.5"}129389http_request_duration_seconds_bucket{le="1"}133988http_request_duration_seconds_bucket{le="+Inf"}144320http_request_duration_seconds_sum53423http_request_duration_seconds_count144320#HELPrpc_duration_secondsAsummaryofRPCdurationsinseconds。#TYPErpc_duration_secondssummaryrpc_duration_seconds{quantile="0.01"}3.102rpc_duration_seconds{quantile="0.05"}3.272rpc_duration_seconds{quantile="0.5"}4.773rpc_duration_seconds{quantile="0.9"}9.001rpc_duration_seconds{quantile="0.99"}76.656rpc_duration_seconds_sum5.7560473e+04rpc_duration_seconds_count2693爬取目标只暴露当前访问的值,不暴露其追踪数据的所有历史指标。指标中的每一行(评论除外)都是时间序列的样本,每个序列仅在同一次捕获中可用。因此,被检测的应用程序只需要跟踪内存中其指标的当前状态,而不需要跟踪或缓存任何历史指标状态。客户端库Prometheus官方已经提供了部分语言的客户端库,包括Go、Java、Python、Ruby,也可以使用一些非官方的第三方客户端库来帮助我们在应用中集成Prometheus指标服务。使用这些库,我们可以创建和跟踪反映服务当前状态的不同类型的指标。这些库都允许我们创建和更新单个指标对象,将它们注册到指标注册表,然后通过HTTP公开该指标注册表。那就是我们常用的metrics接口。Prometheus的instrumentedclientlibrary包含了不同的指标类型:counters,gauges,histograms,andsummaries,对应Prometheus中的指标类型,具体使用哪种指标取决于我们的实际情况。根据不同的指标类型,在构建指标对象时需要提供不同的选项。例如,创建直方图时需要指定桶,但创建计数器时不需要额外的参数。此外,构造的指标对象还为每种类型的指标公开了不同的状态更新方法。例如,计数器有一个增加当前值的方法,但没有公开将计数器设置为任意值的方法,但仪表板允许我们设置当前值。另外,Prometheus客户端库页面(https://prometheus.io/docs/instrumenting/clientlibs/)列出的所有官方库的实现都兼顾了效率和并发安全:效率:更新指标对象的状态优化并发安全性:指标对象的所有状态更新和指标状态的读取都是并发安全的,这意味着我们可以从多个线程(或Go中的goroutines)更新指标值,而不必担心锁,您的应用程序也可以安全地处理多个指标同时获取。所以我们可以放心(当然推荐)使用官方的客户端库来检测我们的应用程序。跟踪指标在检测系统或服务时,尝试提供一些有意义的衡量指标。业内有几个著名的指南可以帮助我们了解应将哪些指标添加到系统中。1.Google的四金指标GoogleSRE手册中有4个金指标,这4个指标主要针对应用或者用户部分。延迟:服务请求所需的时间,例如HTTP请求的平均延迟。需要区分成功和失败的请求,因为失败的请求可能会以非常低的延迟返回不正确的结果。流量:服务容量需求(对于系统)的度量,例如每秒处理的HTTP请求数或数据库系统中的事务数。Errors:请求失败率,用于衡量错误的发生情况,如HTTP500错误次数等显式失败,返回错误内容或无效内容等隐式失败,策略原因导致的失败(如强制响应超过30ms的请求是错误的)。饱和度:衡量资源的使用情况,如内存、CPU、I/O、磁盘使用率(即将饱和的部分,如正在快速填满的磁盘)。2、资源指标的USE方式USE是Utilization(利用率)、Saturation(饱和度)、Error(错误)的组合。它由Netflix的内核和性能工程师BrendanGregg提出,主要用于分析系统性能问题。可以引导用户快速识别资源瓶颈和错误,主要考虑增加以下指标。Utilization:关注系统资源的使用情况。这里的资源主要包括但不限于CPU、内存、网络、磁盘等,100%的利用率通常是系统性能瓶颈的标志。饱和度:比如调度器运行队列的长度,这里主要是针对资源的饱和度(注意和四大黄金指标不同)。任何资源在某种程度上饱和都会导致系统性能下降。错误:发生了多少(以及什么类型)错误。例如,网卡在数据包传输过程中检测到以太网络有10次冲突。3.请求服务系统的RED方法RED方法是WeaveCloud基于Google的4大黄金指标结合Prometheus和Kubernetes容器实践开发的方法论。特别适用于云原生应用和微服务架构应用的监控和测量。在四大黄金指标原则下,RED方法可以有效帮助用户衡量云原生和微服务应用下的用户体验问题。RED方法侧重于以下3个关键指标。请求计数器:请求计数器。错误计数器:错误计数器。请求持续时间:每个请求花费的时间(直方图或摘要)。总的来说,以上三种监控理论的最佳实践是:在遵循Google的四大黄金指标的前提下,对于在线系统,结合RED方法和缓存命中率方法进行监控;对于离线系统或主机监控,使用USE主要方法进行监控;对于批处理系统,可以采用类似Pushgateway的形式进行监控。当然,这些指南不能完全涵盖我们实际的监控需求,但它们为我们应该在应用程序中添加哪些指标提供了很好的指导。Prometheus官方文档(https://prometheus.io/docs/practices/instrumentation/)中的仪器最佳实践提供了更多关于不同类型系统监控的建议。指标名称时间序列的指标名称描述了被监控系统的一些状态,如下图时间序列中的:http_requests_total{job="nginx",instance="localhost:8080",method="POST"}该指标name是标签前面的http_requests_total。指标名称本身的字面意思可以帮助我们理解指标的含义,虽然Prometheus本身并没有对指标名称进行语义解释。为了帮助标准化指标命名,Prometheus官方文档列出了推荐的指标命名最佳实践(https://prometheus.io/docs/practices/naming/#metric-names)。必须符合数据模型中的有效字符必须具有与指标所属域相关的应用程序前缀。这个前缀有时被客户端库称为命名空间。对于特定于某个应用程序的指标,前缀通常是应用程序名称本身。当然,有时指标也比较笼统。例如,prometheus_notifications_total是特定于Prometheus应用程序的指标。http_request_duration_seconds对于所有HTTP请求必须有一个单位。不要将秒与毫秒或字节混用。应使用基本单位,如秒、节、米等应有描述单位的后缀,为复数形式。除了单位之外,累计计数还应该有一个总数作为后缀,例如http_reuqest_duration_seconds、node_memory_usage_bytes、http_requests_total(无单位的累计计数)、process_cpu_seconds_total(有累计计数的单位)、foobar_build_info(用于提供有关元信息的metrics)一个正在运行的应用程序)请注意,直方图和摘要还会生成后缀为_sum、_count和_bucket的计数器(单个直方图桶的计数器)指标,但这些是基于基本指标名称自动生成的直方图,因此我们不需要手动指定这些后缀。给定指标的所有维度的sum()或avg()应该有意义(尽管不一定有用),如果没有,则将数据拆分到多个指标。例如,将各种队列的容量包含在一个度量中是可以的,但是将队列的容量与队列中当前元素的数量混合在一起是不规范的。Label我们知道Label标签是Prometheus中非常重要的元素,在我们对应用进行instrument时为指标指定合适的标签也非常重要。我们知道,每组唯一的标签(包括索引名称)都会识别并自动创建一个唯一的时间序列,普罗米修斯会在查询过程中对其进行跟踪、存储和处理。时间序列的数量也是Prometheus的主要性能瓶颈之一。对于性能稍微好一点的服务器,通常可以很好地处理几百万的时间序列,当然最好不要太大,所以在决定给指标添加哪些标签维度时需要考虑到这一点。Prometheus的总时间序列成本需要通过指标上不同标签维度的乘积得到。比如我们把HTTP请求计数按照状态码和方法进行拆分,那么总的序列数就是不同状态码和不同方法数的乘积,得到这两个维度的所有有效组合,那么就需要将基数乘以同类型的监控目标个数,就可以得到Prometheus服务器整体的时间序列开销,所以控制标签维度非常重要,不能太少,也不能太多。为避免时间序列数字激增,请限制每个标签的可能值数量。特别要避免以下示例:在标签值中存储公共IP地址或电子邮件地址在标签值中存储完整的HTTP路径,如果这些路径包含ID或其他无限信息或类似模式,这将很快产生一个不断增长的时间序列短时间内会使Prometheus服务器过载,所以我们要避免用这种方式标记值。接下来我们将学习使用Prometheus的Go客户端库(https://github.com/prometheus/client_golang)为Go应用添加和暴露监控指标。