保障服务的高可用,必不可少的措施,就是需要对服务资源使用度量情况、运行异常、逻辑错误、请求链路、等各项度量指标、日志和链路了如指掌,并且通过对服务的实时监控和分析,配置指标预警值,对异常进行告警,通知到相关负责人,通过可观测性的提升,预防和及时发现问题,保障服务的可用性。
在可观测性的内容中,可以抽象出三大元素:日志(Logs) 、跟踪(Traces) 、指标(Metrics) ,这三大元素就是可观测性的三大支柱。
日志收集、链路追踪和度量指标都是遥测体系的重要组成部分,它们一起构成了观测系统运行状态和性能的关键数据基础。
下面梳理在从业过程中对于可观测性的相关架构和开源工具的实现原理的理解,这里点到为止,主要让大家了解有哪些技术点,想要了解更具体的内容,可以到搜索中查询,有很多好的详细的文章。
记录并汇集系统运行时产生的日志,包括但不限于错误信息、警告、调试信息以及应用行为细节,这些信息有助于进行问题排查、性能分析和系统审计。
- nginx-err:nginx-log + logstash + es + kibana
- go-error:log-center + kafka + logstash + es +kibana
其中用到的工具:
ELK
Elasticsearch: 分布式搜索与分析引擎(存储日志数据)。
Logstash: 数据收集、过滤与转发工具(Elastic Stack 一部分)。
Kibana: 数据可视化平台(Elastic Stack 一部分)
log-center: 自研 UDP 日志服务
Log-center 是自研的 upd 日志服务,应用服务将日志上报到日志服务,日志服务将日志写入到 kafka,然后再通过 logstash 从 kafka 同步到 ES,研发人员通过 kibana 查询 ES 日志。
kibana 功能还是很强大,除了日志查询,还支持 Visualize 统计图表,Dashboards 仪表板 添加 Panels 等等,具体可以搜索了解相关介绍。
通过 logstash 将 nginx 日志采集上报到 ES,其他和上面一样。
在分布式系统中,尤其是微服部署,服务之间的链路调用错综复杂。链路追踪用于追踪一个请求在整个系统中的传递过程,记录每个服务调用的详细信息,如调用顺序、耗时、状态等,这对于解决分布式系统中的复杂问题和优化系统性能至关重要。
- php apm
- go jeager trace
- kiali istio mesh
其中用到的工具:
Jaeger: 分布式追踪系统,用于微服务和云原生应用的性能监控与故障排查。
Kiali: 服务网格可视化与管理工具(Istio)。
jeager 分布式追踪,链路组成:Span,Trace。
一个 Span 表示 Jaeger 的逻辑工作单元,Span 具有操作名称,操作的开始时间,和持续时间。Span 可以嵌套并排序以建立因果关系模型。
一个 Trace 是通过系统的数据/执行路径,Trace 可被认为是由一组 Span 定义的有向无环图。
收集器直接写入存储
收集器写入 Kafka 作为中间缓冲
- Jaeger Client 为不同语言实现了符合 OpenTracing 标准的 SDK。应用程序通过 API 写入数据,client library 把 trace 信息按照应用程序指定的采样策略传递给 jaeger-agent。
- Agent 它是一个监听在 UDP 端口上接收 span 数据的网络守护进程,它会将数据批量发送给 collector。它被设计成一个基础组件,部署到所有的宿主机上。Agent 将 client library 和 collector 解耦,为 client library 屏蔽了路由和发现 collector 的细节。
- Collector 接收 jaeger-agent 发送来的数据,然后将数据写入后端存储。Collector 被设计成无状态的组件,因此您可以同时运行任意数量的 jaeger-collector。
- Data Store 后端存储被设计成一个可插拔的组件,支持将数据写入 cassandra、elastic search。
- Query 接收查询请求,然后从后端存储系统中检索 trace 并通过 UI 进行展示。
将微服务中的 gRPC 和 HTTP 代码中嵌入追踪相关的代码
- 在 HTTP 服务中集成 Jaeger,早期的做法可能需要在每个请求处理器中显式创建一个新的 Span,并设置父 Span(如果存在)。例如,在 Node.js 中,使用
opentracing
库和jaeger-client
时,需要在中间件中注入追踪逻辑,初始化 Span 并将其绑定到请求上下文中。 - 在 gRPC 服务中,同样需要在每个服务方法的前后创建 Span,通常也需要设置相应的父 Span。gRPC 社区为此提供了拦截器(Interceptor)机制,可以避免直接在业务逻辑中添加追踪代码。通过编写一个 gRPC 拦截器,可以在不修改原有业务逻辑代码的情况下注入 Jaeger 的追踪行为。
存储 mysql ,中间件 redis、kafka ,相关的 client 包也都支持添加追踪的相关拦截的代码。
这样整个链路追踪就可以贯穿应用的各个关系层级,在 jeager ui 中就可以看到从请求发起到服务调用,以及存储操作,中间件操作的整个链路的调用关系。
度量是系统运行时统计的各种量化数据,如 CPU 使用率、内存使用量、网络带宽、请求处理速率、错误率等,这些数据可用于实时监控系统性能、预测潜在问题、制定容量规划、掌握服务水平。
- k8s:k8s-ServiceMonitor + promethus + grafana
- Kafka:kafka-exporter + promethus + grafana
- esc: ecs-exporter + promethus + grafana
- mysql:mysql-exporter + promethus + grafana
- redis:redis-exporter + promethus + grafana
- ...
其中用到的工具:
Grafana:多数据源的监控仪表板与分析工具。
Prometheus: 监控与警报工具,主要用于度量收集与分析
它针对大规模的集群环境设计了拉取式的数据采集方式,你只需要在你的应用里面实现一个metrics
接口,然后把这个接口告诉Prometheus
就可以完成数据采集了。而且还内置了报警功能。
- Prometheus Server: 存储和检索时序数据的核心,定期从配置的监控目标拉取指标。
- Exporter: 各种第三方工具,负责将不同服务和系统的度量数据暴露给 Prometheus,转换成 Prometheus 可读格式。
- Pushgateway(可选): 中间代理,允许短期任务或其他非长驻服务将指标推送到 Prometheus,因为 Prometheus 通常采用的是 Pull 模型。
- PromQL: 专为 Prometheus 设计的时间序列查询语言,用于分析和聚合监控数据。
- Alertmanager: 警报处理组件,对 Prometheus 产生的警报进行管理和通知,包括静默、分组及路由至适当的接收者。
- Web UI : 内置图形界面,用于查询、可视化和浏览 Prometheus 数据以及查看报警状态。
- Client Libraries: 提供给应用开发者直接在代码中集成 Prometheus 监控的库,以便更方便地暴露应用内部的度量指标。
以上各组件共同构成了完整的 Prometheus 监控体系结构,能够实现高效地数据采集、存储、分析和报警功能。
- Counter: 计数器类型,用于表示只增不减的累计值,如请求总数、错误次数等。即使服务重启,计数器也会在下次收集时保留上次的值。它的特点是不能减少,只能增加或重置为零。
- Gauge: 表盘类型,表示任意时刻可增可减的瞬时值,如内存使用量、在线用户数、请求处理速率等。Gauge 可以上升、下降或保持不变,可以用来表示任意变量的状态。
- Histogram : 直方图类型,用于测量观测值的分布情况,例如请求响应时间。它可以自动对观测值进行桶划分,提供观测值落在各个桶内的数量以及总和、平均值等统计信息。
- Summary: 概要统计类型,也用于衡量观测值的分布,但它允许自定义计算百分位数(如 p50, p90, p99),并且可以提供观测值的总次数、总和以及自定义的百分位数数据。与 Histogram 类似,但提供了更多的灵活性和计算精度。
业务指标: 将业务中的一些核心指标、队列长度、异常情况、等业务度量输出,然后通过 grafana 配置面板进行展示和预警, grafana 的使用具体后面会介绍到。
业务应用服务的指标上报,基本都是使用 pull metric 的方式,通过应用服务项目代码接入 prometheus client ,应用服务启动后会同时起一个用于拉取指标的 http 服务,然后在内网中暴露访问端口,prometheus config 来配置抓取应用暴露的指标端点。
资源监控: 通过 exporter 将服务架构中使用到的 esc 、k8s node pod container 、mysql 、redis 、kafka 等,服务器资源,核心功能指标进行上报,同样使用 grafana 展示和预警。
Grafana 是一个监控仪表系统,它可以大大帮助我们简化监控的复杂度,我们只需要提供需要监控的数据,它就可以帮助生成各种可视化仪表,同时它还有报警功能,可以在系统出现问题时发出通知。
Grafana 支持许多不同的数据源,每个数据源都有一个特定的查询编辑器,每个数据源的查询语言和能力都是不同的,我们可以把来自多个数据源的数据组合到一个仪表板,但每一个面板被绑定到一个特定的数据源。
具体的 Web UI 的使用 AlertManager 告警的配置,这里就不介绍,想要了解的可以搜索,总结就是很强大。
我们将日志 ES、指标的 Promethues 加入到 grafana 数据源,然后增加 panel 可视化图表,通过 AlertManager 设置预警值,通过钉钉群通知进行告警通知,整体搭配起来使用是真的香。
ES 日志:可以对日志进行查询可视化展示和监控,比如:请求 qps、异常 5xx 数量、 程序 error 数量、 msyql 慢日志、等请求和程序异常情况的预警。
Promethues 度量: 对上报的业务指标度量进行监控和异常告警,如:队列消费异常、核心功能异常、服务资源、等。
当前接入多个可观测性的工具系统,各系统自相对独立,排查问题只能通过唯一标识 uid 等信息,通过人工的串联信息,如果我们能够在多个系统中进行观测信息的串联,那就可以减去人工匹配的过程,达到事半功倍的效果。如:用户反馈问题或者异常告警,通过从请求异常/请求日志中获得链路的 trace-id,然后在链路追踪中查看用户当前这个请求的链路情况,以及可以查询当前请求所在时刻的服务器节点、 pod、container 资源情况,串联后可以提升人员对问题排查、性能优化分析的效率。
- 如何保障服务的高可用:提升可观测性(当前)
- 如何保障服务的高可用:提升服务性能(预告)
- 如何保障服务的高可用:提升可靠性(预告)
- 如何保障服务的高可用:提升告警应急能力(预告)
预告的文章待后续持续输出,有喜欢的朋友双击 点赞 收藏 👍 + 666🤙
系列收录在 Github《大话 WEB 开发》