关于监控的那些事,你有必要了解一下


做者 | 乔克
php

来源 | 运维开发故事
html

分享 | 乔克
java


监控是整个运维以及产品整个生命周期最重要的一环,它旨在事前可以及时预警发现故障,事中可以结合监控数据定位问题,过后可以提供数据用于分析问题。node

1、监控的目的

监控贯穿应用的整个生命周期。即从程序设计、开发、部署、下线。其主要的服务对象有:git

  • 技术
  • 业务

技术经过监控系统能够了解技术的环境状态,能够帮助检测、诊断、解决技术环境中的故障和问题。然而监控系统的最终目标是业务,是为了更好的支持业务运行,确保业务的持续开展。github

因此监控的目的能够简单概括以下:一、可以对系统进行7*24小时的实时监控 二、可以及时反馈系统状态 三、保证平台的稳定运行 三、保证服务的安全可靠 四、保证业务的持续运行web

2、监控的模式

监控由上至下能够分为:docker

  • 业务监控
  • 应用监控
  • 操做系统

其中业务监控主要是研发提供一些业务指标、业务数据,对其增加率、错误率等进行告警或者展现,须要提早定义规范甚至埋点。应用程序的监控主要有探针和内省。其中探针主要是从外部探测应用程序的特征,好比监听端口是否有响应。内省主要是查看应用程序内部的内容,应用程序经过检测并返回其内部的状态,内部的组件,事务和性能等度量,它能够直接将事件、日志和指标直接发送给监控工具。操做系统主要是监控主要组件的使用率、饱和度以及错误,好比CPU的使用率、CPU的负载等。数据库

3、监控的方式

监控的主要方式有:apache

  • 健康检查。健康检查是对应用自己健康情况的监控,检查服务是否还正常存活。
  • 日志。日志是排查问题的主要方式,日志能够提供丰富的信息用于定位和解决问题。
  • 调用链监控。调用链监控能够完整的呈现出一次请求的所有信息,包括服务调用链路、所耗时间等。
  • 指标监控。指标是一些基于时间序列的离散数据点,经过聚合和计算后能反映出一些重要指标的趋势。

在上述4中监控方式中,健康检查是云平台等基础设施提供的能力,日志则通常有单独的日志中心进行日志的采集、存储、计算和查询,调用链监控通常也有独立的解决方案进行服务调用的埋点、采集、计算和查询,指标监控则是经过一些exporter抓取目标暴露的指标,而后对这些指标数据进行清理、聚合,咱们经过聚合出来的数据进行展现、告警等。

说明:该方案主要是针对指标监控

4、监控选型

4.一、健康检查

云平台提供健康检查能力,直接在云平台中配置。

4.二、日志

成熟的开源日志解决方案是ELK。

4.三、调用链监控

调用链健康使用第三方的健康软件,经常使用的有skywalking、zikpin、pinpoint、elastic APM、Cat。其中zikpin和cat对代码有必定的侵入性,而skywalking、pinpoint、elastic APM是基于字节码注入技术,对代码没有侵入性,并且改动最小。

pinpoint的agent仅支持java和php,而skywalking和elastic APM都支持多种语言,好比java/nodejs/go等。

在云原生环境下,skywalking和elastic APM更适合。

elastic APM直接使用es做为存储,能够在kibana上直接看应用信息,可是其关系图是须要产生必定的费用。skywalking是国人开源的一款产品,已经毕业于Apache 基金会,社区很是活跃,版本迭代很快,专为微服务、云原生架构和基于容器(Docker、K8s、Mesos)架构而设计。

pinpoint和skywalking的对比可参考:http://skywalking.apache.org/zh/blog/2019-02-24-skywalking-pk-pinpoint.html

4.四、指标监控

在云原生环境、传统的监控方式并不适合,在传统环境,zabbix无疑是首选,可是在云原生环境,Prometheus却成为了热门,其主要缘由有:

  • 成熟的社区支撑。Prometheus是CNCF的毕业项目,有许多大厂作背书,社区庞大,是首推的云原生监控解决方案。
  • 易于部署和运维。Prometheus核心只有一个二进制文件,没有其余的第三方依赖,部署运维均十分方便。
  • 采用Pull模型,经过HTTP的Pull方式从各个监控目标拉取监控数据。Push模型通常经过Agent方式去采集信息并推送到收集器中,每一个服务的Agent都须要配置监控数据项与监控服务端的信息,在大量服务时会加大运维难度;另外,采用Push模型,在流量高峰期间监控服务端会同时接收到大量请求和数据,会给监控服务端形成很大压力,严重时甚至服务不可用。
  • 强大的数据模型。Prometheus采集到的监控数据均以指标的形式存在于内置的时序数据库中,除了基本的指标名称外,还支持自定义的标签。经过标签能够定义出丰富的维度,方便进行监控数据的聚合和计算。
  • 强大的查询语言PromQL。经过PromQL能够实现对监控数据的查询、聚合、可视化、告警。
  • 完善的生态。常见的操做系统、数据库、中间件、类库、编程语言,Prometheus都提供了接入方案,而且提供了Java/Golang/Ruby/Python等语言的客户端SDK,可以快速实现自定义的监控逻辑。
  • 高性能。Prometheus单一实例便可处理数以百计的监控指标,每秒处理数十万的数据,在数据采集和查询方面有着优异的性能表现。

注意:因为采集的数据有可能丢失,Prometheus并不适合对采集数据要求100%准确的场景。

5、Prometheus监控系统概述

监控系统的总体框架以下:

  • Prometheus Server:用于抓取指标、存储时间序列数据
  • exporter:暴露指标让任务来抓
  • pushgateway:push 的方式将指标数据推送到该网关
  • alertmanager:处理报警的报警组件
  • adhoc:用于数据查询

其流程很简单,Prometheus server端能够直接接收或者经过pushgateway获取到数据,存储到TSDB中,而后对数据进行规则整理,经过Altermanager进行报警或者经过Grafana等工具进行展现。

6、指标监控的对象

监控系统通常采用分层的方式划分监控对象。在咱们的监控系统中,主要关注如下几种类型的监控对象:

  • 主机监控,主要指主机节点软、硬件资源的一些监控数据。

  • 容器环境监控,主要指服务所处运行环境的一些监控数据。

  • 应用服务监控,主要指服务自己的基础数据指标,提现服务自身的运行情况。

  • 第三方接口监控,主要指调用其余外部服务接口的状况。

对于应用服务和第三方接口监控,咱们经常使用的指标包括:响应时间、请求量QPS、成功率。

6.一、主机监控

6.1.一、为何须要主机监控

主机是系统的载体,一切系统应用都运行在主机之上,若是某台或者几台主机宕机,会致使上面运行的因此应用都没办法正常提供服务,严重者致使生产事故。因此对主机的监控与预警是很是有必要的,咱们能够在其出故障以前对其进行处理,避免严重的事故发生。

6.1.二、如何判断资源状况

主机的监控主要从一下三个方面来综合考虑其状态:

  • 使用率:资源忙于工做的平均时间,一般是随时间变化的百分比
  • 饱和度:资源队列的长度
  • 错误:资源错误事件的计数

6.1.三、哪些资源须要监控

主机的主要资源对象有:

  • CPU
  • 内存
  • 磁盘
  • 可用性
  • 服务状态
  • 网络

6.1.四、如何进行监控

在Prometheus监控方案中,主机的资源指标是经过node-exporter来进行采集,而后存储在Prometheus时序数据库里,而后能够经过PromQL来查询各个指标的具体状况。

一、CPU

CPU主要从使用率和饱和度来进行监控。(1)、使用率,指标node_cpu_seconds_total一般会根据CPU使用率超过多少来进行告警,好比当CPU使用率大于80%,则进行告警,固然CPU是一个Gauge类型的,它的数据是会上下增减的,因此咱们在判断CPU使用率的时候一般是一段时间内CPU持续高达多少的时候才进行告警,好比下面的表达式就是统计5分钟内CPU使用率大于60%的主机:

100-(avg(irate(node_cpu_seconds_total{mode="idle"}[5m])) by(instance)* 100) > 60

CPU指标还有用户态、内核态的指标数据,这个根据状况来进行监控。(2)、饱和度,指标node_loadCPU的饱和度一般指的是CPU的负载状况。正常状况下CPU的总体负载不超过CPU的总数,好比2颗CPU,则负载不超过2。咱们收集到的指标有1分钟、5分钟、15分钟的负载数据,在配置监控的时候选择好统计时间,通常状况下会选择5分钟的负载做为统计,以下表示5分钟的负载大于CPU的总数的2倍:

node_load5 > on (instance) 2 * count by(instance)(node_cpu_seconds_total{mode="idle"})
二、内存

内存主要从使用率和饱和度来进行监控。(1)、使用率 内存的使用率能够直观的看到总体CPU的使用状况,其计算方式使用(free + buffer + cache)/ total。指标主要有:

  • node_memory_MemTotal_bytes:主机上的总内存
  • node_memory_MemFree_bytes:主机上的可用内存
  • node_memory_Buffers_bytes:缓冲缓存中的内存
  • node_memory_Cached_bytes:页面缓存中的内存

好比下面的表达式是用于统计内存使用率大于80%:

100 - sum(node_memory_MemFree_bytes{job="node-exporter"} + node_memory_Buffers_bytes{job="node-exporter"} + node_memory_Cached_bytes{job="node-exporter"})by (instance) / sum(node_memory_MemTotal_bytes{job="node-exporter"})by(instance)*100 > 80

(2)、饱和度 内存的饱和度是指内存和磁盘的读写状况来监控。指标有:

  • node_vmstat_pswpin:系统每秒从磁盘读到内存的字节数,单位KB
  • node_vmstat_pswpout:系统每秒从内存写到磁盘的字节数,单位KB
三、磁盘

磁盘的监控有点特殊,咱们不按着USE的方法去测量。若是单考虑其使用率并无多大的效果,由于10G剩余20%和1T剩余20%对咱们的影响是不同的,因此咱们能够监控其增加趋势以及方向。好比:根据前面1h的磁盘增加状况来预测在4h内是否会把磁盘用完。

predict_linear(node_filesystem_free_bytes{job="node-exporter",mountpoint!=""}[1h], 4*3600) 

固然,若是仅仅这样预测也会产生不少垃圾告警,由于在某一小时的增加速度可能很快,这样算下来预测会在接下来的4小时内使用完,可是咱们登上主机一看,才用了40%,这时候就算有告警咱们也不会处理。因此咱们还能够再加一个条件,好比磁盘使用率大于80%而且在接下来的4小时内会使用完。以下:

(100 - (node_filesystem_avail_bytes{fstype!="",job="node-exporter"} / node_filesystem_size_bytes{fstype!="",job="node-exporter"} * 100)>80) and (predict_linear(node_filesystem_free_bytes{job="node-exporter",mountpoint!="",device!="rootfs"}[1h],4 * 3600) < 0)

除此以外,咱们还须要监控磁盘的IO,不管是云主机磁盘仍是物理磁盘,每块盘都有其对应的IOPS,若是某个主机的IO很高,也会致使其余的问题,好比系统繁忙、负载很高等状况。node-exporter中定义了其指标,仅须要对其进行聚合,而后对聚合后的数据进行页面展现或者告警处理。其聚合公式以下:

100-(avg(irate(node_disk_io_time_seconds_total[1m])) by(instance)* 100)
四、可用性

可用性是指的主机可用性,咱们能够经过up指标来判断主机是否可用,若是其值等于0表示宕机,等于1表示存活。好比下面便可表示主机不可用:

up{job="node-exporter"}==0
五、服务状态

服务状态旨在监控关键服务,好比docker.service,ssh.service,kubelet.service等。指标为:

  • node_systemd_unit_state

好比监听docker.service的服务状态为存活:

node_systemd_unit_state{name="docker.service",state="active"} == 1

监控主要服务,以便于咱们能在服务出问题的第一时间收到消息进行处理。

六、网络

网络主要是监控其在每台主机上的出入流量,还有TCP链接状态。prometheus的node-exporter会抓取每台主机的网卡以及其出入网卡的流量,还有每台主机的TCP状态,咱们能够将须要的指标进行聚合,根据聚合后的指标数据再进行页面展现或者告警处理。好比统计流入的流量:

((sum(rate (node_network_receive_bytes_total{device!~'tap.*|veth.*|br.*|docker.*|virbr*|lo*'}[5m])) by (instance)) / 100)

统计流出的流量:

((sum(rate (node_network_transmit_bytes_total{device!~'tap.*|veth.*|br.*|docker.*|virbr*|lo*'}[5m])) by (instance)) / 100) 

以及统计TCP状态为ESTABLISHED的数量:

node_netstat_Tcp_CurrEstab

咱们能够根据每一个指标作对应的监控以及告警。

6.二、容器监控

6.2.一、为何须要容器监控

在云原生时代,容器是咱们应用的载体,它至关于应用的基础设施,因此对其的监控是颇有必要的。咱们在建立一个容器的时候每每会给其cpu和内存一个限制值,特别是内存,若是其使用达到了限制值,就会致使OOM,这时候咱们就会作升级配置或查找缘由处理。

6.2.二、监控的指标对象主要有哪些

监控对象主要有一下:

  • cpu
  • memory
  • 事件

6.2.三、如何进行监控

咱们使用cAdvisor来获取容器指标(kubelet已经集成了这个服务)。

一、CPU

在容器中,就简单经过其使用率来监控其状态,咱们经过其(使用量/limit)来获得其使用率。以下:

sum(
          node_namespace_pod_container:container_cpu_usage_seconds_total:sum_rate
        * on(namespace,pod)
          group_left(workload, workload_type) mixin_pod_workload
        ) by (workload, workload_type,namespace,pod)
        /sum(
          kube_pod_container_resource_limits_cpu_cores
        * on(namespace,pod)
          group_left(workload, workload_type) mixin_pod_workload
        ) by (workload, workload_type,namespace,pod) * 100 > 80

若是CPU的使用率持续大于咱们设定的阈值,则考虑增长CPU的Limit值。

二、memory

和CPU同样,经过其使用率来观察容器的内存是否充足。以下:

sum(
            container_memory_working_set_bytes
          * on(namespace,pod)
            group_left(workload, workload_type) mixin_pod_workload
        ) by (namespace,pod) / sum(
            kube_pod_container_resource_limits_memory_bytes
          * on(namespace,pod)
            group_left(workload, workload_type) mixin_pod_workload
        ) by (namespace,pod) * 100 / 2 > 80

若是内存的使用率大于咱们设定的阈值,则考虑是否须要增长Pod的内存了。

三、事件

这里的事件针对的是kubernetes的pod事件。在Kubernetes中,事件分为两种,一种是Warning事件,表示产生这个事件的状态转换是在非预期的状态之间产生的;另一种是Normal事件,表示指望到达的状态,和目前达到的状态是一致的。咱们用一个Pod的生命周期进行举例,当建立一个Pod的时候,首先Pod会进入Pending的状态,等待镜像的拉取,当镜像录取完毕并经过健康检查的时候,Pod的状态就变为Running。此时会生成Normal的事件。而若是在运行中,因为OOM或者其余缘由形成Pod宕掉,进入Failed的状态,而这种状态是非预期的,那么此时会在Kubernetes中产生Warning的事件。那么针对这种场景而言,若是咱们可以经过监控事件的产生就能够很是及时的查看到一些容易被资源监控忽略的问题。

在kubernetes中经过kube-eventer来进行事件监控,而后针对不一样的事件来进行告警通知。

6.三、应用服务监控

6.3.一、为何须要应用服务监控

应用是业务的载体,也是用户最直观的体验,应用的状态与否直接关系到业务的优良以及用户的体验。若是没有对其作好必定的监控措施,可能会出现如下问题:

  • 没法识别或诊断故障
  • 没法衡量应用程序的运行性能
  • 没法衡量应用程序或组件的业务指标以及成功与否,例如跟踪销售数据或交易价值

6.3.二、有哪些监控指标

  • 应用程序监控
    • HTTP接口:URL存活、请求量、耗时、异常量

    • JVM :GC次数、GC耗时、各个内存区域的大小、当前线程数、死锁线程数

    • 线程池:活跃线程数、任务队列大小、任务执行耗时、拒绝任务数

    • 链接池:总链接数、活跃链接数

  • 业务指标:视业务来定,好比PV、订单量等

6.3.三、如何进行监控

一、应用程序监控

应用程序指标能够衡量应用程序的性能和状态,包括应用程序最终用户的体验,如延迟和响应时间。在这背后,咱们测量了应用程序的吞吐量:请求、请求量、事务和事务时间。「(1)、HTTP接口监控」可使用prometheus的blackbox_exporter来进行接口存活的监控,能够用于对http,https,tcp,dns以及ICMP协议进行探测,从而抓取数据进行监控。

「(2)、JVM监控」经过在应用中埋点来暴露JVM数据,使用Prometheus监控采集JVM数据,借助Prometheus Grafana大盘来展现JVM数据,并建立报警,便可实现利用Prometheus监控JVM的目的。(1)、在pom.xml文件中添加Maven依赖。

<dependency>
    <groupId>io.prometheus</groupId>
    <artifactId>simpleclient_hotspot</artifactId>
    <version>0.6.0</version>
</dependency>

(2)、在能够执行初始化的位置添加初始化JVM Exporter的方法。

@PostConstruct
    public void initJvmExporter() {
        io.prometheus.client.hotspot.DefaultExports.initialize();
    }

(3)、在/src/main/resources/application.properties文件中配置用于Prometheus监控的端口(Port)和路径(Path)

management.port: 8081
endpoints.prometheus.path: prometheus-metrics

(4)、在/src/main/java/com/monitise/prometheus_demo/PrometheusDemoApplication.java文件中打开HTTP端口

@SpringBootApplication
// sets up the prometheus endpoint /prometheus-metrics
@EnablePrometheusEndpoint
// exports the data at /metrics at a prometheus endpoint
@EnableSpringBootMetricsCollector
public class PrometheusDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(PrometheusDemoApplication.class, args);
    }
}

而后在部署应用的时候暴露接口和数据就能够进行采集了。因为应用比较多就能够经过自动发现的方式来作。咱们在service中加上下面的annotations,就能够自动发现了。

prometheus.io/scrape: 'true'
prometheus.io/path: '/prometheus-metrics'
prometheus.io/port: '8081'
二、业务指标监控

业务指标是应用程序指标的更进一层,它们一般与应用程序指标同义。若是你考虑将对特定服务的请求数量做为应用程序指标进行测量,那么业务指标一般会对请求的内容执行某些操做。一个应用程序指标的示例多是测量支付交易的延迟,相应的业务指标多是每一个支付交易的价值。业务指标可能包括新用户/客户的数量、销售数量、按价值或位置划分的销售额,或者其余任何有助于衡量业务情况的指标。

6.四、第三方接口监控

6.4.一、为何须要第三方接口监控

第三方接口的优良直接影响自身业务,因此对第三方接口的异常状况监控是很是重要的。主要是其的响应时间、存活性以及成功率。

6.4.二、有哪些监控指标

  • 响应时间
  • 存活性
  • 成功率

6.4.三、如何进行监控

可使用prometheus的blackbox_exporter来进行接口的监控。经过第三方接口监控的维度,咱们能够方便地将自身服务与所使用到的第三方服务关联起来,以统一的视图展现服务用到了哪些第三方服务接口、这些第三方服务接口的响应时间和成功率是多少。当服务出现异常时,对于定位问题有很大帮助;同时,一些内部的服务可能监控报警并不全面,第三方监控也能帮助他们提高服务质量。

7、告警通知

达到什么阈值须要告警?对应的故障等级是多少?不须要处理的告警不是好告警,可见定义合理的阈值有多重要,不然只会下降运维效率或者让监控系统失去它的做用。

Prometheus容许基于PromQL定义报警的触发条件,Prometheus周期性的对PromQL进行计算,当知足条件时就会向Alertmanager发送报警信息。

在配置告警规则的时候,咱们将按组进行分类,这样就能够对相同组下的告警进行聚合,方便配置以及查看。Alertmanager在接收到报警后,能够对报警进行分组、抑制、静默等额外处理,而后路由到不一样的接收器。Alertmanager支持多种报警通知方式,除经常使用的邮件通知外,还支持钉钉、企业微信等方式,也支持经过webhook自定义通知方式。咱们能够按轻重缓急定义不一样的通知方式,这样就能够根据不一样通知方式采起不一样的措施。

8、故障处理流程

收到故障告警后,必定要有相应的处理流程和oncall机制,让故障及时被跟进处理。

8.一、故障等级划分

在处理故障以前,须要先清晰的认识是什么样的故障,而后再采起什么样的措施。因此咱们就须要对故障等级作一个划分。例如将系统故障等级按照《信息系统安全等级保护基本要求》具体划分为四个等级,一级和二级故障为重大故障;三级和四级故障为通常性故障。

8.1.一、一级故障

系统发生故障,预计将已经严重影响公司生产业务系统,致使相关生产业务系统中断1小时以上,并预计24小时之内没法恢复的,具有如下一个或几个特征,既定义为一级故障。

  1. 公司机房网络与阿里云VPC网络出现故障,致使工做人员和用户没法访问相关业务系统;
  2. WEB网站和APP系统等关键服务器宕机或有其余缘由致使拒绝提供服务的;
  3. 利用技术手段形成业务数据被修改、假冒、泄漏、窃取的信息系统安全事件;
  4. 由病毒形成关键业务系统不能正常提供服务。

8.1.二、二级故障

信息系统发生故障,预计将或已经严重影响公司生产业务系统,致使相关生产业务系统中断1小时以上,并预计24小时之内能够恢复的,具有如下一个或几个特征,即定义为二级故障。

  1. 公司机房网络与阿里云VPC出现线路和设备故障;
  2. WEB网站和APP系统等关键服务器宕机或有其余缘由致使拒绝提供服务的;
  3. 12小时之内没法解决的三级故障。

8.1.三、三级故障

知足如下条件之一,即定义为三级故障。

  1. 故障发生后,影响到信息系统的运行效率,速度变慢,但不影响业务系统访问;
  2. 故障发生后预计在12小时之内恢复;
  3. 24小时之内没法解决的四级故障

8.1.四、四级故障

知足如下条件之一,即定义为四级故障。

  1. 故障发生后,可随时应急处理,不会影响系统的全面运行;
  2. 生产业务系统设备因病毒攻击等缘由,形成网络数据出现偶尔掉包,但不影响系统的正常访问和运行。

8.二、故障处理程序

8.2.一、故障发现

工做人员在发现故障或接收到故障报告后,首先要记录故障发生时间和发现时间,及发现部门,发现人及联系电话,对故障的等级进行初步断定,并报告相关人员进行处理。

8.2.二、故障处理

  1. 发生故障的系统通知到运维人员,运维人员应先询问了解设备和配置近期的变动状况,查清故障的影响范围,从而肯定故障的等级和发生故障的可能位置;
  2. 对于通常性故障按照规定的故障升级上报要求进行上报,并在处理过程当中及时向主管领导通报故障处理状况;
  3. 对于重大故障按照规定的故障升级上报要求进行上报,并在处理过程当中及时向主管领导通报故障处理状况。

8.2.三、故障上报

根据故障等级和发生的时限,要对故障的状况进行及时的上报,并对报告人,告知人际时间内容进行记录。重大故障由故障处理组领导负责上报,通常性故障由故障处理人员负责上报。故障升级上报时限以下表所示:

上报时限 一级故障 二级故障 三级故障 四级故障
当即 运维主管 运维人员 运维人员 运维人员
半小时 技术总监 运维主管

1小时
技术总监 运维主管
4小时

技术总监
12小时


运维主管
24小时



8.三、故障处理流程图






公众号:运维开发故事

github:https://github.com/orgs/sunsharing-note/dashboard

爱生活,爱运维

若是你以为文章还不错,就请点击右上角选择发送给朋友或者转发到朋友圈。您的支持和鼓励是我最大的动力。喜欢就请关注我吧~

扫码二维码

关注我,不按期维护优质内容

舒适提示

若是你喜欢本文,请分享到朋友圈,想要得到更多信息,请关注我。

                                              ........................


本文分享自微信公众号 - 运维开发故事(mygsdcsf)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索