1. 为什么要监控?
- 分散在各个服务器上的日志如何处理?
- 业务流程出现问题,如何快速的定位问题发生在哪个环节、哪个点?
- 如何实现事故的预警,如资源不足?
- 如果服务出现下线,如何能第一时间做出响应?
- 如何分析性能的瓶颈?
- 如何确保系统在稳定运行?
2. 监控体系和分类
2.1. 四层监控体系
四层监控体系 |
业务监控 (数据是否入库、web页面是否正常响应......) |
应用层监控 (mysql、redis、kafka、docker、微服务健康......) |
系统层监控 (linux、windows......) |
基础设施层 (网络、交换机、流量......) |
2.2. 监控分类
- 日志监控
- Metrics监控
- 调用链监控
- 告警系统
- 健康检查
3. 监控目标
在《SRE: Google运维解密》一书中指出,监控系统需要能够有效的支持白盒监控和黑盒监控。通过白盒能够了解其内部的实际运行状态,通过对监控指标的观察能够预判可能出现的问题,从而对潜在的不确定因素进行优化。而黑盒监控,常见的如HTTP探针,TCP探针等,可以在系统或者服务在发生故障时能够快速通知相关的人员进行处理。通过建立完善的监控体系,从而达到以下目的:
- 长期趋势分析:通过对监控样本数据的持续收集和统计,对监控指标进行长期趋势分析。例如,通过对磁盘空间增长率的判断,我们可以提前预测在未来什么时间节点上需要对资源进行扩容。
- 对照分析:两个版本的系统运行资源使用情况的差异如何?在不同容量情况下系统的并发和负载变化如何?通过监控能够方便的对系统进行跟踪和比较。
- 告警:当系统出现或者即将出现故障时,监控系统需要迅速反应并通知管理员,从而能够对问题进行快速的处理或者提前预防问题的发生,避免出现对业务的影响。
- 故障分析与定位:当问题发生后,需要对问题进行调查和处理。通过对不同监控监控以及历史数据的分析,能够找到并解决根源问题。
- 数据可视化:通过可视化仪表盘能够直接获取系统的运行状态、资源使用情况、以及服务运行状态等直观的信息。
3.1. 黑盒监控
3.1.1. 什么是黑盒监控?
黑盒监控(Black Box Monitoring)是一种监控方法,它通过观察和评估系统的外部行为和输出来获得对系统的洞察。在黑盒监控中,监控系统没有内部访问权限,因此只能通过外部接口和公开可见的指标来监视系统的性能、功能和可用性。
黑盒监控将系统视为一个封闭的盒子,只关注系统的输入和输出,而不考虑内部实现细节。它主要关注以下方面:
- 功能性监控:黑盒监控可以验证系统是否按照预期执行其功能。例如,对于一个网站,黑盒监控可以检查关键页面是否可以正常加载,链接是否可点击等。
- 性能监控:黑盒监控可以用于测量系统的性能和响应时间。它可以检测到潜在的性能问题,如慢速响应、高延迟等。
- 可用性监控:黑盒监控可以帮助确定系统的可用性和稳定性。它可以检测到系统是否处于正常运行状态,或者是否存在故障或不可访问的情况。
- 安全监控:黑盒监控可以帮助检测系统的安全漏洞和风险。通过模拟常见攻击和异常情况,黑盒监控可以暴露系统中的潜在安全问题。
3.1.2. 如何进行黑盒监控?
HTTP探针和TCP探针都是网络监控和分析中常见的工具,用于检测和分析网络通信的状态、性能和可用性。下面我将简单介绍它们的作用和区别:
3.1.2.1. HTTP探针
HTTP探针通常用于监测HTTP协议在网络中的传输情况。它可以帮助管理员或开发人员监控网站或Web应用的性能、响应时间、状态码等信息。通过向特定URL发送HTTP请求并分析响应,HTTP探针可以提供关于网络服务的实时状态和性能数据。
一些常见的用途包括:
- 监控网站的可用性和响应时间
- 检测网站的页面加载速度
- 分析网站返回的状态码(如200、404、500等)
- 检测HTTP头部信息
3.1.2.2. TCP探针
TCP探针则是用来监控TCP协议连接的工具。TCP探针可以用于检测TCP连接的建立时间、稳定性、断开情况等。通过发送TCP数据包并监听响应,TCP探针可以帮助监视TCP连接的状态并识别潜在的网络问题。
一些常见的用途包括:
- 监控TCP连接的延迟和丢包率
- 检测TCP连接的可靠性和稳定性
- 跟踪TCP连接的建立和关闭过程
3.2. 白盒监控
3.2.1. 什么是白盒监控?
白盒监控是一种针对软件系统内部运行情况的监控方式,通过收集和分析系统内部的详细信息来监视系统的性能、稳定性和安全性。白盒监控通常涉及对应用程序代码、数据库查询、服务调用等内部细节的监控和分析。
白盒监控可以提供对系统内部运行情况的深入了解,有助于发现潜在的性能瓶颈、异常行为和安全风险。这种监控方式通常与应用程序的内部实现直接相关,因此需要在代码级别或者底层系统组件上进行集成和配置。
白盒监控通常包括以下方面的内容:
- 性能监控:对代码执行时间、内存占用、CPU 使用率等性能指标进行监控和分析,以便发现潜在的性能瓶颈并进行优化。
- 错误和异常监控:监控应用程序中的错误、异常抛出情况,以便及时发现并解决潜在的问题。
- 安全监控:监控系统中的安全事件、访问控制、数据泄露等安全相关情况,以保障系统的安全性。
- 日志和跟踪:收集和分析应用程序的日志数据和调用链信息,以便追踪问题和分析系统行为。
4. 监控技术栈体系
从应用体系角度来看,我们可以选择监控所有层级,也可以选择任意一个层级的任意应用;
从监控体系来看,我们可以选择使用所有监控技术,也可以选择任意一个监控技术监控其对应的应用层级。
整个监控体系跟应用程序的耦合性较低。同时,每一个监控体系我们都实现了发现异常后向钉钉告警,并且具有数据可视化的界面。
5. 监控技术栈详情
5.1. Actuator + Admin
5.1.1. 什么是Actuator、Admin?
Spring Boot Actuator是Spring Boot提供的一个功能模块,主要用于对应用系统进行自省和监控。通过Actuator,开发者可以很方便地对应用系统某些监控指标进行查看、统计等。
Actuator的核心是端点(Endpoint),用来监视应用程序及交互。Spring Boot Actuator中已经内置了非常多的Endpoint,如health、info、beans、metrics、httptrace、shutdown等,同时也允许开发者自己扩展Endpoint。每个Endpoint都可以启用和禁用,要远程访问Endpoint,还必须通过JMX或HTTP进行暴露,大部分应用选择HTTP。
Spring Boot Admi使用Vue开发,用来展示Actuator采集回来的各种指标数据,Admin也只需要简单的配置即可使用,如果不需要实现数据的可视化,或者想自定义数据的可视化,我们可以忽略Admin的搭建和使用。
5.1.2. Actuator的优势
- 丰富的监控端点:健康检查、信息展示、环境属性、配置信息、日志管理等,开发人员和运维人员可以通过这些端点获取应用程序运行时的各种信息。
- 自定义端点:可以根据需求扩展自定义的监控端点,以便暴露应用程序特定的监控信息。
- 安全性:提供了安全的监控端点,可以通过 Spring Security 或其他安全机制进行保护,从而确保敏感信息不被未授权的用户访问。
- 问题诊断:提供了线程情况、请求跟踪、堆栈跟踪等端点,有助于开发人员在应用程序出现问题时进行诊断和调试。
- 搭建便捷:Spring Boot内置的功能模块,只需要简单的配置即可完成基本使用。
5.1.3. Actuator实践
我们使用Actuator主要用来监测各个微服务的各种端点状况(如:微服务的健康状态、微服务的线程、微服务的JVM内存使用情况、GC等等),这些监控回来的数据我们将通过另一个组件——Spring Boot Admin进行可视化展示。
通常来讲,我们使用Actuator重点关注各个微服务的健康状态(包含微服务所关联的各种中间件),当微服务的监控状态发生变化后,我们将会产生告警并发送钉钉。同时,由上面的技术栈图可以看出,Actuator所采集的数据是没有做存储的,所以我们不需要考虑数据存储和高可用的问题。
5.2. Promethues + Grafana
5.2.1. 为什么选择Promethues?
选择 Prometheus 并不是偶然,因为:
- Prometheus 是按照 《Google SRE 运维之道》的理念构建的,具有实用性和前瞻性。
- Prometheus 社区非常活跃,基本稳定在 1个月1个版本的迭代速度,从 2016 年 v1.01 开始接触使用以来,到目前发布到 v2.13.x ,你会发现 Prometheus 一直在进步、在优化。
- Go 语言开发,性能优越,安装部署简单,多平台部署兼容性好。
- 时序数据库,丰富的数据收集客户端,官方以及第三方提供了各种常用开源 exporter。
- 丰富强大的查询能力。
- 对云原生 Kubernetes 支持友好。
5.2.2. Promethues的优势
Prometheus是一个开源的完整监控解决方案,其对传统监控系统的测试和告警模型进行了彻底的颠覆,形成了基于中央化的规则计算、统一分析和告警的新模型。 相比于传统监控系统Prometheus具有以下优点:
5.2.2.1. 易于管理
Prometheus核心部分只有一个单独的二进制文件,不存在任何的第三方依赖(数据库,缓存等等)。唯一需要的就是本地磁盘,因此不会有潜在级联故障的风险。
Prometheus基于Pull模型的架构方式,可以在任何地方(本地电脑,开发环境,测试环境)搭建我们的监控系统。对于一些复杂的情况,还可以使用Prometheus服务发现(Service Discovery)的能力动态管理监控目标。
5.2.2.2. 强大的数据模型
所有采集的监控数据均以指标(metric)的形式保存在内置的时间序列数据库当中(TSDB)。所有的样本除了基本的指标名称以外,还包含一组用于描述该样本特征的标签。
如下所示:
http_request_status{code='200',content_path='/api/path', environment='produment'} => [value1@timestamp1,value2@timestamp2...]
http_request_status{code='200',content_path='/api/path2', environment='produment'} => [value1@timestamp1,value2@timestamp2...]
每一条时间序列由指标名称(Metrics Name)以及一组标签(Labels)唯一标识。每条时间序列按照时间的先后顺序存储一系列的样本值。
表示维度的标签可能来源于你的监控对象的状态,比如code=404或者content_path=/api/path。也可能来源于的你的环境定义,比如environment=produment。基于这些Labels我们可以方便地对监控数据进行聚合,过滤,裁剪。
5.2.2.3. 强大的查询语言PromQL
Prometheus内置了一个强大的数据查询语言PromQL。 通过PromQL可以实现对监控数据的查询、聚合。同时PromQL也被应用于数据可视化(如Grafana)以及告警当中。
通过PromQL可以轻松回答类似于以下问题:
- 在过去一段时间中95%应用延迟时间的分布范围?
- 预测在4小时后,磁盘空间占用大致会是什么情况?
- CPU占用率前5位的服务有哪些?(过滤)
5.2.2.4. 高效
对于监控系统而言,大量的监控任务必然导致有大量的数据产生。而Prometheus可以高效地处理这些数据,对于单一Prometheus Server实例而言它可以处理:
- 数以百万的监控指标。
- 每秒处理数十万的数据点。
5.2.2.5. 可扩展
Prometheus是如此简单,因此你可以在每个数据中心、每个团队运行独立的Prometheus Sevrer。Prometheus对于联邦集群的支持,可以让多个Prometheus实例产生一个逻辑集群,当单实例Prometheus Server处理的任务量过大时,通过使用功能分区(sharding)+联邦集群(federation)可以对其进行扩展。
5.2.2.6. 易于集成
使用Prometheus可以快速搭建监控服务,并且可以非常方便地在应用程序中进行集成。目前支持: Java, JMX, Python, Go,Ruby, .Net, Node.js等等语言的客户端SDK,基于这些SDK可以快速让应用程序纳入到Prometheus的监控当中,或者开发自己的监控数据收集程序。同时这些客户端收集的监控数据,不仅仅支持Prometheus,还能支持Graphite这些其他的监控工具。
同时Prometheus还支持与其他的监控系统进行集成:Graphite, Statsd, Collected, Scollector, muini, Nagios等。
Prometheus社区还提供了大量第三方实现的监控数据采集支持:JMX, CloudWatch, EC2, MySQL, PostgresSQL, Haskell, Bash, SNMP, Consul, Haproxy, Mesos, Bind, CouchDB, Django, Memcached, RabbitMQ, Redis, RethinkDB, Rsyslog等等。
5.2.2.7. 可视化
Prometheus Server中自带了一个Prometheus UI,通过这个UI可以方便地直接对数据进行查询,并且支持直接以图形化的形式展示数据。同时Prometheus还提供了一个独立的基于Ruby On Rails的Dashboard解决方案Promdash。
最新的Grafana可视化工具也已经提供了完整的Prometheus支持,基于Grafana可以创建更加精美的监控图标。基于Prometheus提供的API还可以实现自己的监控可视化UI。
5.2.3. Promethues实践
我们使用Promethues可以实现白盒监控和黑盒监控。白盒监控,主要用Promethues来监测Docker容器的相关信息、各种中间件(Mysql、Redis、Kafka的相关信息)、linux/windows系统的基本信息等;黑盒监控,主要用Promethues来监测Web/小程序业务层面的相关信息,如:配置一个url地址,HTTP探针定时请求url,获取里面所有接口的返回状态,如果code=404/500.....,则告知告警系统作出告警。
5.3. Loki + Grafana
5.3.1. 什么是Loki?
Loki是由Grafana Labs开源的一个水平可扩展、高可用性,多租户的日志聚合系统的日志聚合系统。它的设计初衷是为了解决在大规模分布式系统中,处理海量日志的问题。Loki采用了分布式的架构,并且与Prometheus、Grafana密切集成,可以快速地处理大规模的日志数据。该项目受 Prometheus 启发,官方的介绍是: Like Prometheus,But For Logs.。
文章标题:《真香,Grafana开源Loki日志系统取代ELK?》
5.3.2. Loki的优势
Loki 作为日志聚合和查询系统具有许多优势,以下是一些 Loki 的主要优势:
5.3.2.1. 高度可扩展性
Loki 的分布式架构设计使其能够轻松扩展以处理大规模系统生成的大量日志数据。用户可以根据需要水平扩展 Loki,以满足不断增长的日志存储和查询需求。
5.3.2.2. 低成本存储
Loki 使用压缩算法和索引技术来降低存储成本,与传统的日志存储系统相比,Loki 的存储成本更低,使得用户能够更经济高效地存储大量日志数据。
5.3.2.3. 易于集成和部署
Loki 与 Grafana 集成紧密,用户可以通过 Grafana 轻松地可视化和监控日志数据。此外,Loki 也提供了 Helm Chart 和 Docker 镜像等便捷的部署方式,使用户能够快速部署和配置 Loki 系统。
5.3.2.4. 标准化日志格式
Loki 支持各种日志格式,但推荐使用标准化的 JSON 格式,这有助于提高日志的可读性、可搜索性和可索引性,使用户能够更轻松地对日志数据进行分析和查询。
5.3.3. Loki和ELK的对比
5.3.3.1. 存储方式
架构 | 存储方式 | 优势 |
Loki | LogQL 存储引擎 | 更加节省存储空间,并且具有更高的查询性能 |
ELK | Elasticsearch |
5.3.3.2. 查询语言
架构 | 查询语言 | 优势 |
Loki | 类似 PromQL 的 LogQL 查询语言 | 更好的可读性和易用性,并且更适合对时间序列数据进行查询 |
ELK | Lucene |
5.3.3.3. 部署与配置
架构 | 部署与配置 | 优势 |
Loki | 相对较复杂,需要设置各种参数和插件以适应不同的场景 | 更加轻松地部署和配置 Loki 系统 |
ELK | Helm Chart 和 Docker 镜像等部署方式 |
5.3.3.4. Grafana集成
架构 | Grafana集成 | 优势 |
Loki | 可以集成 | 更加紧密地与 Grafana 集成,提供了更多的面板和模板以支持日志数据的可视化和监控 |
ELK | 可以集成 |
5.3.4. Loki实践
在微服务架构下,各个微服务的日志比较分散,当我们在开发调试时,如果遇到多个微服务之间的调用,那么我们在查看日志时非常的麻烦。因为项目使用Docker部署,所以我们可以使用Loki对Docker的日志进行收集和监控。
收集监控后,我们就可以非常方便地在Grafana中灵活切换日志,实时查询各个微服务的日志了。并且具备过滤和条件查询的功能。同时,我们还可以集成Promethues,对日志进行自定义告警。
6. 总结
监控技术 | 监控对象 | 资源占用 | 是否存储监控数据 |
Spring Boot Actuator+ Spring Boot Admin | java应用程序的各种健康状态、JVM内存、线程信息、日志等级、GC回收情况等 | 小 | 不存储 |
Promethues + Grafana | 各种常用中间件(Redis、Mysql、Kafka等)、Docker容器信息、黑盒监控 | 中(可大可小) | 存储 |
Loki + Grafana | 应用程序日志、系统日志、容器日志、微服务日志 | 小 | 存储 |
上面阐述了常见的第三方监控工具的相关基本信息,还有一个自研的以fastApi作为web框架的平台没有阐述,如果感兴趣的话小伙伴多的话,后面我也会单独把每一个监控技术栈都详细的梳理清楚,包括如何搭建使用等。欢迎大家讨论交流!