● 分散在各个服务器上的日志如何处理?
● 业务流程出现问题,如何快速的定位问题发生在哪个环节、哪个点?
● 如何实现事故的预警,如资源不足?
● 如果服务出现下线,如何能第一时间做出响应?
● 如何分析性能的瓶颈?
● 如何确保系统在稳定运行?
在《SRE: Google 运维解密》一书中指出,监控系统需要能够有效的支持白盒监控和黑盒监控。通过白盒能够了解其内部的实际运行状态,通过对监控指标的观察能够预判可能出现的问题,从而对潜在的不确定因素进行优化。而黑盒监控,常见的如 HTTP 探针,TCP 探针等,可以在系统或者服务在发生故障时能够快速通知相关的人员进行处理。通过建立完善的监控体系,从而达到以下目的:
● 长期趋势分析:通过对监控样本数据的持续收集和统计,对监控指标进行长期趋势分析。例如,通过对磁盘空间增长率的判断,我们可以提前预测在未来什么时间节点上需要对资源进行扩容。
● 对照分析:两个版本的系统运行资源使用情况的差异如何?在不同容量情况下系统的并发和负载变化如何?通过监控能够方便的对系统进行跟踪和比较。
● 告警:当系统出现或者即将出现故障时,监控系统需要迅速反应并通知管理员,从而能够对问题进行快速的处理或者提前预防问题的发生,避免出现对业务的影响。
● 故障分析与定位:当问题发生后,需要对问题进行调查和处理。通过对不同监控监控以及历史数据的分析,能够找到并解决根源问题。
● 数据可视化:通过可视化仪表盘能够直接获取系统的运行状态、资源使用情况、以及服务运行状态等直观的信息。
黑盒监控(Black Box Monitoring)是一种监控方法,它通过观察和评估系统的外部行为和输出来获得对系统的洞察。在黑盒监控中,监控系统没有内部访问权限,因此只能通过外部接口和公开可见的指标来监视系统的性能、功能和可用性。
黑盒监控将系统视为一个封闭的盒子,只关注系统的输入和输出,而不考虑内部实现细节。它主要关注以下方面:
HTTP 探针和 TCP 探针都是网络监控和分析中常见的工具,用于检测和分析网络通信的状态、性能和可用性。下面我将简单介绍它们的作用和区别:
HTTP 探针通常用于监测 HTTP 协议在网络中的传输情况。它可以帮助管理员或开发人员监控网站或 Web 应用的性能、响应时间、状态码等信息。通过向特定 URL 发送 HTTP 请求并分析响应,HTTP 探针可以提供关于网络服务的实时状态和性能数据。
一些常见的用途包括:
● 监控网站的可用性和响应时间
● 检测网站的页面加载速度
● 分析网站返回的状态码(如 200、404、500 等)
● 检测 HTTP 头部信息
TCP 探针则是用来监控 TCP 协议连接的工具。TCP 探针可以用于检测 TCP 连接的建立时间、稳定性、断开情况等。通过发送 TCP 数据包并监听响应,TCP 探针可以帮助监视 TCP 连接的状态并识别潜在的网络问题。
一些常见的用途包括:
● 监控 TCP 连接的延迟和丢包率
● 检测 TCP 连接的可靠性和稳定性
● 跟踪 TCP 连接的建立和关闭过程
白盒监控是一种针对软件系统内部运行情况的监控方式,通过收集和分析系统内部的详细信息来监视系统的性能、稳定性和安全性。白盒监控通常涉及对应用程序代码、数据库查询、服务调用等内部细节的监控和分析。
白盒监控可以提供对系统内部运行情况的深入了解,有助于发现潜在的性能瓶颈、异常行为和安全风险。这种监控方式通常与应用程序的内部实现直接相关,因此需要在代码级别或者底层系统组件上进行集成和配置。
白盒监控通常包括以下方面的内容:
从应用体系角度来看,我们可以选择监控所有层级,也可以选择任意一个层级的任意应用;
从监控体系来看,我们可以选择使用所有监控技术,也可以选择任意一个监控技术监控其对应的应用层级。
整个监控体系跟应用程序的耦合性较低。同时,每一个监控体系我们都实现了发现异常后向钉钉告警,并且具有数据可视化的界面。
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 的搭建和使用。
我们使用 Actuator 主要用来监测各个微服务的各种端点状况(如:微服务的健康状态、微服务的线程、微服务的 JVM 内存使用情况、GC 等等),这些监控回来的数据我们将通过另一个组件——Spring Boot Admin 进行可视化展示。
通常来讲,我们使用 Actuator 重点关注各个微服务的健康状态(包含微服务所关联的各种中间件),当微服务的监控状态发生变化后,我们将会产生告警并发送钉钉。同时,由上面的技术栈图可以看出,Actuator 所采集的数据是没有做存储的,所以我们不需要考虑数据存储和高可用的问题。
选择 Prometheus 并不是偶然,因为:
● Prometheus 是按照《Google SRE 运维之道》的理念构建的,具有实用性和前瞻性。
● Prometheus 社区非常活跃,基本稳定在 1 个月 1 个版本的迭代速度,从 2016 年 v1.01 开始接触使用以来,到目前发布到 v2.13.x ,你会发现 Prometheus 一直在进步、在优化。
● Go 语言开发,性能优越,安装部署简单,多平台部署兼容性好。
● 时序数据库,丰富的数据收集客户端,官方以及第三方提供了各种常用开源 exporter。
● 丰富强大的查询能力。
● 对云原生 Kubernetes 支持友好。
Prometheus 是一个开源的完整监控解决方案,其对传统监控系统的测试和告警模型进行了彻底的颠覆,形成了基于中央化的规则计算、统一分析和告警的新模型。 相比于传统监控系统 Prometheus 具有以下优点:
Prometheus 核心部分只有一个单独的二进制文件,不存在任何的第三方依赖 (数据库,缓存等等)。唯一需要的就是本地磁盘,因此不会有潜在级联故障的风险。
Prometheus 基于 Pull 模型的架构方式,可以在任何地方(本地电脑,开发环境,测试环境)搭建我们的监控系统。对于一些复杂的情况,还可以使用 Prometheus 服务发现 (Service Discovery) 的能力动态管理监控目标。
所有采集的监控数据均以指标 (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 我们可以方便地对监控数据进行聚合,过滤,裁剪。
Prometheus 内置了一个强大的数据查询语言 PromQL。 通过 PromQL 可以实现对监控数据的查询、聚合。同时 PromQL 也被应用于数据可视化 (如 Grafana) 以及告警当中。
通过 PromQL 可以轻松回答类似于以下问题:
● 在过去一段时间中 95% 应用延迟时间的分布范围?
● 预测在 4 小时后,磁盘空间占用大致会是什么情况?
● CPU 占用率前 5 位的服务有哪些?(过滤)
对于监控系统而言,大量的监控任务必然导致有大量的数据产生。而 Prometheus 可以高效地处理这些数据,对于单一 Prometheus Server 实例而言它可以处理:
● 数以百万的监控指标。
● 每秒处理数十万的数据点。
Prometheus 是如此简单,因此你可以在每个数据中心、每个团队运行独立的 Prometheus Sevrer。Prometheus 对于联邦集群的支持,可以让多个 Prometheus 实例产生一个逻辑集群,当单实例 Prometheus Server 处理的任务量过大时,通过使用功能分区 (sharding)+ 联邦集群 (federation) 可以对其进行扩展。
使用 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 等等。
Prometheus Server 中自带了一个 Prometheus UI,通过这个 UI 可以方便地直接对数据进行查询,并且支持直接以图形化的形式展示数据。同时 Prometheus 还提供了一个独立的基于 Ruby On Rails 的 Dashboard 解决方案 Promdash。
最新的 Grafana 可视化工具也已经提供了完整的 Prometheus 支持,基于 Grafana 可以创建更加精美的监控图标。基于 Prometheus 提供的 API 还可以实现自己的监控可视化 UI。
我们使用 Promethues 可以实现白盒监控和黑盒监控。白盒监控,主要用 Promethues 来监测 Docker 容器的相关信息、各种中间件(Mysql、Redis、Kafka 的相关信息)、linux/windows 系统的基本信息等;黑盒监控,主要用 Promethues 来监测 Web/小程序业务层面的相关信息,如:配置一个 url 地址,HTTP 探针定时请求 url,获取里面所有接口的返回状态,如果 code=404/500.....,则告知告警系统作出告警。
Loki 是由 Grafana Labs 开源的一个水平可扩展、高可用性,多租户的日志聚合系统的日志聚合系统。它的设计初衷是为了解决在大规模分布式系统中,处理海量日志的问题。Loki 采用了分布式的架构,并且与 Prometheus、Grafana 密切集成,可以快速地处理大规模的日志数据。该项目受 Prometheus 启发,官方的介绍是: Like Prometheus,But For Logs.。
Loki 作为日志聚合和查询系统具有许多优势,以下是一些 Loki 的主要优势:
Loki 的分布式架构设计使其能够轻松扩展以处理大规模系统生成的大量日志数据。用户可以根据需要水平扩展 Loki,以满足不断增长的日志存储和查询需求。
Loki 使用压缩算法和索引技术来降低存储成本,与传统的日志存储系统相比,Loki 的存储成本更低,使得用户能够更经济高效地存储大量日志数据。
Loki 与 Grafana 集成紧密,用户可以通过 Grafana 轻松地可视化和监控日志数据。此外,Loki 也提供了 Helm Chart 和 Docker 镜像等便捷的部署方式,使用户能够快速部署和配置 Loki 系统。
Loki 支持各种日志格式,但推荐使用标准化的 JSON 格式,这有助于提高日志的可读性、可搜索性和可索引性,使用户能够更轻松地对日志数据进行分析和查询。
架构 | 存储方式 | 优势 |
---|---|---|
Loki | LogQL 存储引擎 | 更加节省存储空间,并且具有更高的查询性能 |
ELK | Elasticsearch |
架构 | 查询语言 | 优势 |
---|---|---|
Loki | 类似 PromQL 的 LogQL 查询语言 | 更好的可读性和易用性,并且更适合对时间序列数据进行查询 |
ELK | Lucene |
架构 | 部署与配置 | 优势 |
---|---|---|
Loki | ELK Helm Chart 和 Docker 镜像等部署方式 | 更加轻松地部署和配置 Loki 系统 |
ELK | 相对较复杂,需要设置各种参数和插件以适应不同的场景 |
架构 | Grafana 集成 | 优势 |
---|---|---|
Loki | 可以集成 | 更加紧密地与 Grafana 集成,提供了更多的面板和模板以支持日志数据的可视化和监控 |
ELK | 可以集成 |
在微服务架构下,各个微服务的日志比较分散,当我们在开发调试时,如果遇到多个微服务之间的调用,那么我们在查看日志时非常的麻烦。因为项目使用 Docker 部署,所以我们可以使用 Loki 对 Docker 的日志进行收集和监控。
收集监控后,我们就可以非常方便地在 Grafana 中灵活切换日志,实时查询各个微服务的日志了。并且具备过滤和条件查询的功能。同时,我们还可以集成 Promethues,对日志进行自定义告警。
监控技术 | 监控对象 | 资源占用 | 是否存储监控数据 |
---|---|---|---|
Spring Boot Actuator+ Spring Boot Admin | java 应用程序的各种健康状态、JVM 内存、线程信息、日志等级、GC 回收情况等 | 小 | 不存储 |
Promethues + Grafana | 各种常用中间件(Redis、Mysql、Kafka 等)、Docker 容器信息、黑盒监控 | 中(可大可小) | 存储 |
Loki + Grafana | 应用程序日志、系统日志、容器日志、微服务日志 | 小 | 存储 |
上面阐述了常见的第三方监控工具的相关基本信息,还有一个自研的以 fastApi 作为 web 框架的平台没有阐述,如果感兴趣的话小伙伴多的话,后面我也会单独把每一个监控技术栈都详细的梳理清楚,包括如何搭建使用等。欢迎大家讨论交流!