首页 > 其他分享 >【升职加薪秘籍】我在服务监控方面的实践(5)-应用监控

【升职加薪秘籍】我在服务监控方面的实践(5)-应用监控

时间:2023-08-10 16:24:45浏览次数:44  
标签:http 加薪 接口 指标 pprof prometheus 监控 升职

大家好,我是蓝胖子,关于性能分析的视频和文章我也大大小小出了有一二十篇了,算是已经有了一个系列,之前的代码已经上传到github.com/HobbyBear/performance-analyze,接下来这段时间我将在之前内容的基础上,结合自己在公司生产上构建监控系统的经验,详细的展示如何对线上服务进行监控,内容涉及到的指标设计,软件配置,监控方案等等你都可以拿来直接复刻到你的项目里,这是一套非常适合中小企业的监控体系。

前面我们完成了日志监控系统的搭建,这一节将会介绍在开发中比较紧密的应用服务监控的内容了。

项目代码已经上传到github

github.com/HobbyBear/easymonitor

首先要搞懂对于应用服务的监控,我们需要监控哪些东西。

第一个就是应用现在提供服务的质量,通过在【升职加薪秘籍】我在服务监控方面的实践(1)-监控蓝图 里那一节里介绍的四大黄金指标可以很好反应这一点,分别是延迟,流量,错误数,饱和度,这四个维度可以映射为应用程序的接口处理时长,qps,接口报错数,饱和读可以从应用服务的当前协程,线程数,cpu,内存等指标反映出来。

第二个是应用的内部运行状态的指标,应用服务质量可以看成是从应用外部观察应用的运行状态。内部运行状态的指标,像垃圾回收,协程调度延迟,这些指标则是从应用自身运行时框架反应出来的,这些指标在分析应用服务产生的问题时会很有帮助。这些指标也一般会由程序语言提供,或者语言周边的工具也会有提供,像golang程序,是语言自带的有这些指标暴露出来。

第三个方面是应用保留现场的能力,这个方面其实不属于建立监控指标了,而是程序在出问题时,能够主动的对问题现场留下分析证据。拿golang程序来说,通过go tool pprof的相关命令能够分析出应用程序此时使用cpu或者内存,协程等资源的情况,并且关联到具体的代码,而程序出问题时,如果能够自动执行这样的命令就能达到保留问题现场的目的。

下面,我们挨个看下对于这3个方面,我们应该怎么做。

为应用服务建立黄金指标

前面我们提到过四大黄金指标反应到应用程序上就是,接口处理时长,qps,接口报错数,饱和读可以从应用服务的当前协程,线程数,cpu,内存等指标反映出来。

现在我们来看看如何如何在程序代码里融入它们。

接口处理时长

我们需要通过prometheus来暴露这些指标,在golang里,有prometheus 客户端库,我们引入它。

github.com/prometheus/client_golang/prometheus

关于prometheus 指标的几种类型,分别有counter,guage,histogram,summary,对于histogram不好理解的同学可以看看我之前的两篇文章prometheus描点原理prometheus Histogram 统计原理 ,基本上懂了histogram,其余指标类型就都容易理解了。

注意,因为这一节内容涉及到promql语句的书写,所以对prometheus描点不熟悉的同学最好还是看完prometheus描点原来再来学习本节的内容

对于接口时长的统计,一般会采用histogram指标类型统计接口的耗时分位数,比如p99分位数,代表在100个请求里,按接口耗时从小到大排列,第99个接口耗时多大。

histogram类型的指标代码定义如下,type 代表接口的类型,除了http,还可以表示grpc等等,method值的get,post等请求方式,status值请求的响应码,api是接口的路由,

var serverHandleHistogram = prometheus.NewHistogramVec(prometheus.HistogramOpts{  
   Name: "server_handle_seconds",  
}, []string{"type", "method", "status", "api"})

在这个指标里并没有标签表面指标来自哪个服务的,是因为在prometheus配置文件里我们已经指明了服务名和机器节点,配置如下:

global:  
  scrape_interval:     15s # 默认抓取周期  
scrape_configs:  
  - job_name: 'webapp'  
    scrape_interval: 5s  
    metrics_path: /metrics  
    static_configs:  
      - targets: [ 'mynode:8090' ]  
    relabel_configs:  
      - source_labels: [ __address__ ]  
        target_label: instance  
        regex: (.*):\d+  
        replacement: $1

这样会在采集指标时,默认加上这两个维度。

要开启这个指标需要往指标的注册中心进程注册,代码如下

var (  
   MetricsReg = prometheus.NewRegistry()  
)
MetricsReg.MustRegister(serverHandleHistogram)

接着启动一个http endpoint对外暴露指标信息,代码如下

http.Handle("/metrics", promhttp.HandlerFor(MetricsReg, promhttp.HandlerOpts{Registry: MetricsReg}))  
go func() {  
   http.ListenAndServe(":8090", http.DefaultServeMux)  
}()

指标记录的时机可以放在http路由中间件里面去做,这样在请求处理逻辑前后,我们正好可以进行相关的埋点操作。代码如下,我们在next.ServeHTTP是实际的业务处理逻辑,处理完以后,通过RecordServerHandlerSeconds对请求的时长进行统计,并且还对不是200的请求做了日志记录。

func MetricMiddleware(next http.Handler) http.Handler {  
   return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {  
      rw := &responseWriter{ResponseWriter: w}  
      // 在处理请求之前执行的逻辑  
      // 可以在这里进行请求验证、日志记录等操作  
      reqBody, err := httputil.DumpRequest(r, true)  
      if err != nil {  
         log.Errorf("dump request fail err=%s", err)  
      }  
      now := time.Now()  
      // 调用下一个处理程序  
      next.ServeHTTP(rw, r)  
      RecordServerHandlerSeconds(TypeHTTP, r.Method, rw.Status(), r.URL.Path, time.Now().Sub(now).Seconds())  
      if rw.Status() != http.StatusOK {  
         log.Warnf("request fail request=%s code=%d", string(reqBody), rw.statusCode)  
      }  
   })  
}

注意,由于请求量可能比较多,不可能对所有请求参数以及响应结果都进行记录,所以我们可以选择性的按某些条件去筛选请求进行日志记录,比如这里我将接口失败的请求记录下来,方便往后的问题排查。

当需要看某段时间内接口的耗时情况时,我们可以这样写promql语句:

histogram_quantile(0.9,sum(irate(server_handle_seconds_bucket{}[5m])) by (le,host)) > 0 

上面的promql就代表按主机维度看每台主机接口的p90分位数接口耗时是多少。你也可以按接口路由或者其他维度对耗时进行聚合统计,

注意下,我们的histogram_quantile表达式的值都限制了 > 0 ,这是因为histogram_quantile在计算分位数时,如果发现桶的元素少于两个就会返回NAN,所以需要去掉这种干扰元素。

qps

接着我们看下qps的指标如何埋点,记录qps的指标可以采用prometheus的counter类型对接口请求数进行累加,利用irate或者rate函数对其进行计算斜率得到qps。

定义counter类型的指标代码如下:

serverHandleCounter = prometheus.NewCounterVec(prometheus.CounterOpts{  
   Name: "server_handle_total",  
}, []string{"type", "method", "api"})

和接口耗时统计类似,我们同样是将qps的埋点放在中间件里。

func RecordServerCount(metricType string, method string, api string) {  
   serverHandleCounter.With(prometheus.Labels{  
      "type":   metricType,  
      "method": method,  
      "api":    api,  
   }).Inc()  
}

func MetricMiddleware(next http.Handler) http.Handler {  
   return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {  
       ....
      // 对qps进行埋点统计 
      RecordServerCount(TypeHTTP, r.Method, r.URL.Path)  
      next.ServeHTTP(rw, r)  
      .....
   })  
}

计算qps,可以这样来写promql,通过sum by语句将各个主机相同的接口路由聚合起来,查看5m内接口的qps是多少。

sum(irate(server_handle_total{type="http"}[5m])) by (api,method)

接口报错数

接着,我们看下接口报错数如何写promql语句来观察。我们创建histogram指标时会创建一个server_handle_seconds_count 指标,它表示桶中一共记录了多少个记录。由于我们的指标标签上有status维度,所以可以按接口路由维度筛选出那些失败的接口路由随时间变化的情况。api路径和方法名唯一确定一条路由。

sum(rate(server_handle_seconds_sum{type="http",status !="200"}[5m])) by (api,method)

应用程序饱和度 以及 runtime内部监控

应用程序的饱和度可以拿当前服务正在处理的请求数已经当前应用程序占用的cpu已以及内存信息去判定,当达到一个比较高的水位后,应用程序的接口耗时在处于增大的趋势则可以认为应用服务达到了饱和。

在golang的 prometheus client已经帮我们暴露了这些指标,同时也暴露了runtime内部的指标,例如垃圾回收耗时等。我们只需要像下面那样在指标注册中心注册便可以暴露它们了。

MetricsReg = prometheus.NewRegistry()

MetricsReg.MustRegister(  
   collectors.NewGoCollector(  
      collectors.WithGoCollectorRuntimeMetrics(collectors.GoRuntimeMetricsRule{Matcher: regexp.MustCompile("/.*")}),  
   ),  
   collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}),  
)

对应的promql语句的写法和监控面板配置可以看github项目代码里的配置,通过导入面板的json模板就可以了,这块比较简单,我就不再继续展开了。

自动化pprof机制 保留问题现场

最后我们来看下如何保留问题现场,要解决这个问题,首先要确定触发问题发生的条件,这些条件可以是协程数量达到某个值,也可以是cpu,内存上涨,也可以是接口qps达到某个上限。

接着便是如何保留问题现场的问题。在golang里,我们可以通过go tool pprof 工具来分析应用程序的cpu,内存等资源的消耗以及代码阻塞情况,并将其定位到具体的代码。关于pprof 工具的原理我之前出过一个系列:

# golang pprof 监控系列(1) —— go trace 统计原理与使用

# golang pprof监控系列(2) —— memory,block,mutex 使用

# golang pprof 监控系列(3) —— memory,block,mutex 统计原理

# golang pprof 监控系列(4) —— goroutine thread 统计原理

# golang pprof 监控系列(5) —— cpu 占用率 统计原理

如果能在问题发生时自动执行pprof 相关的命令,生成了pprof文件,就可以后续通过pprof文件分析当时程序是哪段逻辑导致的问题了。

目前已经有相关的开源工具在做这件事情,holmes这个项目实现了这个逻辑

https://github.com/mosn/holmes

但是注意,生成的pprof文件只能在出现问题的机器上,所以要分析pprof文件还得再去对应机器上进行下载,这在机器过多时,可能不太方便,所以你完全可以写一个程序,自动将生成的pprof文件上传到一台机器上,pprof文件可以用 应用名+机器名+时间+采集类型 取名,这样在看pprof文件时也更加方便。

总结

这一节,通过对应用服务建立黄金指标和使用holmes做到保留问题现场,构建起了对应用服务的监控。并且你可以回忆整个过程,是不是在指标异常的时候,我们可以很方便快速的定位到问题代码,这也是监控的目的,不仅发现问题,还要能定位问题。在下一节我将会介绍如何从对mysql进行监控,并且能够通过mysql监控指标,找到应用代码不合理有风险的地方。

在万千人海中,相遇就是缘分,为了这份缘分,给作者点个赞

标签:http,加薪,接口,指标,pprof,prometheus,监控,升职
From: https://www.cnblogs.com/hobbybear/p/17620681.html

相关文章

  • VLAN监控及常见问题排查
    局域网,我们通常称为LAN,是一种由基于同一地理位置的设备组成的网络,可实现它们之间的通信,局域网的虚拟对应物是虚拟局域网或VLAN。VLAN增强了LAN,提供了进行更改的灵活性、更高的可扩展性和更好的安全性。使用VLAN的好处VLAN具有虚拟的优势,在LAN中,所有连接的设备必须位于同一......
  • 5G工业网关实现智能工厂数据采集远程监控
    5G工业网关是一种用于连接采集和管理工业设备、系统的重要设备。它是在工业物联网(IIoT)环境中使用的,依靠5G通信网络实现可靠、高速的数据传输和处理,是未来智能制造通用的网络之一,具有以下功能:1、高速连接:5G工业网关具备连接5G网络的能力,可以提供更高的带宽和更低的延迟,以支持实时数......
  • 监控Elasticsearch的关键指标
    Elasticsearch的核心职能就是对外提供搜索服务,所以搜索请求的吞吐和延迟是非常关键的,搜索是靠底层的索引实现的,所以索引的性能指标也非常关键,Elasticsearch由一个或多个节点组成集群,集群自身是否健康也是需要我们监控的。lasticSearch的架构非常简单,一个节点就可以对外提供服务,......
  • 如何利用PowerShell来监控一个进程中的线程数
    如何利用PowerShell来监控一个进程实际产生了多少个线程$processName="chrome.exe"$process=Get-WmiObject-Query"SELECT*FROMWin32_ProcessWHEREName='$processName'"$threadCount=$process.ThreadCountWrite-Host"Thenumberofthreadsin......
  • 图扑 Web SCADA 智慧钢厂能源监控 HMI
    前言钢铁行业作为我国的支柱产业,也是我国能源消耗的重点行业之一,随着国家节能减排政策的推进,有效实施能源管控是企业提高能源绩效、降低能源成本和提高核心竞争力的重要途径。通过对钢铁企业能耗现状和能源管理模式的分析可以得知,我国钢铁企业若想实现绿色发展,需以理念转变为基础,以......
  • SSL证书分类和SSL免费证书申请和证书监控
    SSL证书分类简称全称中文意思DVDomainvalidated域名认证OVOrganizationvalidated组织认证EVExtendedvalidation扩展认证SSL免费证书申请服务商网址阿里云百度云腾讯云华为云站长之家Cloudflarehttps://www.cloudflare.com/zh-cn/ssl/滴滴云(停止服务)https://www.didiyun.com/p......
  • 设备使用RTMP推流到安防监控EasyCVR视频汇聚平台,为何只有FLV格式无法播放?
    TSINGSEE青犀视频安防监控视频汇聚平台EasyCVR基于云边端一体化架构,具有强大的数据接入、处理及分发能力,可提供视频监控直播、云端录像、云存储、录像检索与回看、智能告警、平台级联、云台控制、语音对讲、智能分析等功能。智能视频监控平台EasyCVR可支持的协议非常多,包括国标G......
  • TSINGSEE青犀视频安防监控视频平台EasyCVR设备在线,视频无法播放的原因排查
    可支持国标GB28181、RTMP、RTSP/Onvif、海康Ehome、海康SDK、大华SDK、宇视SDK等多种协议接入的安防监控视频平台EasyCVR基于云边端一体化架构,具有强大的数据接入、处理及分发能力,可在复杂的网络环境中,将分散的各类视频资源进行统一汇聚、整合、集中管理。智能视频监控EasyCVR平台......
  • MySQL——《监控Zabbix部署》
    一、简介zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案。zabbix能监视各种网络参数,保证服务器系统的安全运营;并提供灵活的通知机制以让系统管理员快速定位/解决存在的各种问题。zabbix由2部分构成,zabbixserver与可选组件zabbixagent。......
  • 安防视频监控平台EasyNVR页面无法上传授权文件,该如何进行授权?
    TSINGSEE青犀视频安防监控平台EasyNVR可支持设备通过RTSP/Onvif协议接入,并能对接入的视频流进行处理与多端分发,包括RTSP、RTMP、HTTP-FLV、WS-FLV、HLS、WebRTC等多种格式。在智慧安防等视频监控场景中,EasyNVR可提供视频实时监控直播、云端录像、云存储、录像检索与回看、告警等视......