K8s下Dubbo监控体系搭建:Prometheus+Grafana+AlertManager实践

发布时间:2026/10/22 11:59:38
K8s下Dubbo监控体系搭建:Prometheus+Grafana+AlertManager实践 如果你也是按节奏在 Kubernetes 上交付 Dubbo 服务前三天我们多半已经处理了集群基础、注册中心、配置中心和服务编排到了第四天真正躲不开的一个环节就是监控交付。这篇文章是这个系列的第二天但核心不变把一个能真正帮到你排查问题的 Dubbo 监控体系落到 K8s 里。不是装一个 Grafana 看个心跳图就完事而是要让 Dubbo 的接口级别指标、Pod 实例状态、线程池压力和告警链路全部打通并且所有配置都能被后面的交付复制。适合已经完成服务部署、想补齐监控的交付同学也适合刚接触 K8s 监控的新手从零理解为什么要这样搭。1. 交付 Dubbo 监控前先把方案骨架搭起来1.1 监控组件怎么选一条链路解决三件事很多人一想到监控第一反应是“先装个 Grafana”这个顺序其实容易翻车。Grafana 只是展示层真正决定监控是否好用的是指标从哪来、如何采集、如何触发告警。我的选择很固定Prometheus 负责采集和存储Grafana 负责展示AlertManager 负责通知。这三个组件在 K8s 生态里配合最成熟和 Dubbo 的指标暴露方式也天然兼容。Dubbo 本身支持将运行时指标导出为 Prometheus 格式这意味着不需要在业务代码里埋太多自定义埋点只要打开指标开关服务就会在某个端口吐出类似dubbo_provider_requests_total这样的数据。Prometheus 按“拉取”模式工作会定期主动访问这些端口。相比让服务自己把数据“推”到监控平台拉取模式在 K8s 这种实例随时增减的环境里更可靠新 Pod 起来后只要你给它打上正确标签Prometheus 就能自动发现实例下线后目标自动消失不用担心告警误报。你可能也会看到有人用老式的“Dubbo Monitor 中心”它靠服务把统计数据上报到中心再由中心存库展示。这个方案在固定机房里能用但到了 K8s 上服务实例动不动就扩容缩容上报链路要维护的点太多数据也存在单点库风险。我的观点很直接除非你还在维护古董版本否则这次交付就把监控底座统一到 Prometheus 体系上来省掉后面一堆中间层。1.2 监控到底该看哪些指标先想清楚看什么再动手配否则告警规则无从写起。对 Dubbo 服务来说核心是四类指标请求量每个 provider 服务的 RPC 调用量通常按接口或方法维度区分能帮你判断业务流量是否上涨、某条链路是否被大量调用。延迟Dubbo 调用耗时尤其要看 P99、P95而不是只看平均值。平均值会被慢调用拉平一条超时链路可能被其他正常请求掩盖。成功率错误请求占总请求的比例。这个指标比告警“进程挂没挂”更灵敏因为进程存活时业务可能已经在大量报错。饱和度线程池活跃数、等待队列大小、IO 使用率。Dubbo 服务崩溃之前往往先出现线程池打满、请求排队。这四类指标不是平级的。请求量是基础延迟和成功率决定用户体验饱和度决定系统还能扛多久。我习惯在交付时先让这四个维度都裸奔可看再根据业务诉求订告警阈值而不是一上来就堆几十个面板。1.3 采集链路全景从 Metrics 到 Grafana 面板整条链路并不复杂脑子里要装下这样一条路径每个 Dubbo 服务通过 Spring Boot 或独立 RPC 启动后暴露/metrics端点K8s 里每个提供 RPC 的服务都有一个 ServicePrometheus 通过 ServiceMonitor 找到符合条件的 Service进而拿到背后的 Pod 地址抓回来的指标存进 Prometheus规则引擎按预定义表达式生成告警并推给 AlertManagerGrafana 从 Prometheus 查数据并渲染面板。这条路径里最容易出问题的点在“ServiceMonitor 能否匹配到正确的 Service”这一步。K8s 中 Pod IP 是动态的Prometheus 不能配置一个固定的 target 列表必须通过标签选择器动态发现。所以交付监控的本质工作是把服务、ServiceMonitor、Prometheus 三者用标签串起来。2. 让 Dubbo 服务先把指标吐出来2.1 在服务里开启 Metrics我遇到不少案例服务部署得漂漂亮亮最后监控面板一片空白原因很简单应用根本没开指标暴露端口。所以交付监控的第一件事不是搭 Prometheus而是回服务代码里把 Dubbo Metrics 打开。以 Dubbo 3.x 为例引入依赖并开启配置后服务就会在一个独立端口或 RPC 端口旁暴露指标。以下是我在项目中常用的一种配置方式dependency groupIdorg.apache.dubbo/groupId artifactIddubbo-metrics-prometheus/artifactId /dependency对应的 application.yml 配置大致是dubbo: application: name: order-provider metrics: enable: true prometheus: enable: true port: 20880不同 Dubbo 版本里的配置项名称可能有差异有的版本用protocol里的 exporter 配置有的版本通过dubbo.metrics.port指定端口。我的建议是不要照搬这一段先去 Dubbo 官方文档确认你那个版本是否支持指标导出如果支持直接访问/metrics能看到 Prometheus 格式的指标即可。这里有一个容易踩的坑很多人把 metrics 端口和 RPC 端口混在一起。理论上可以但我建议单独开一个端口比如 20880 继续做 RPC指标端口用 20881 或者干脆用独立的管理端口。原因很简单Prometheus 的访问负载和业务 RPC 流量分开后不会因为指标抓取影响线上调用另外告警时排查问题也更清楚看到某个端口流量异常能立刻判断是业务流量还是监控流量。2.2 用注解把采集目标“钉”到工作负载上Dubbo 服务部署到 K8s 后Prometheus 需要知道从哪里抓数据。最常见的一种方式是在 Service 上打注解Prometheus 自带的prometheus.io自动发现规则会去读取这组注解。我实际使用的 Service 配置类似下面这样apiVersion: v1 kind: Service metadata: name: order-provider namespace: mall annotations: prometheus.io/scrape: true prometheus.io/path: /metrics prometheus.io/port: 20881 labels: app: order-provider component: dubbo-provider spec: selector: app: order-provider ports: - name: dubbo port: 20880 targetPort: 20880 - name: metrics port: 20881 targetPort: 20881注意prometheus.io/port是字符串不是数字。这个取值必须和 Service 里的端口名或端口号对应。如果配成 20881但 Pod 里指标端口实际是 8081那 Prometheus 抓取就会超时。注解方式适合小团队、监控基础设施还没上 Prometheus Operator 的场景。它简单直观在 Service 上加了注解Prometheus 就能靠自带的 Kubernetes 服务发现机制找到目标。缺点是每个服务都要手动管这组注解服务一多容易漏而且注解只解决“发现”不解决“规则”。2.3 ServiceMonitor 绑定动态发现还是直接抓取取决于你的运维模式如果你们的 K8s 环境已经用 Prometheus Operator我更推荐用 ServiceMonitor。ServiceMonitor 是一个自定义资源专门用来描述“Prometheus 应该抓哪些 Service 的哪些端口”。它比注解更工程化所有监控对象的定义都是 YAML可以做版本管理也可以批量生成。下面是一个能直接套用的 ServiceMonitor 示例apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: dubbo-provider-monitor namespace: mall labels: team: delivery spec: selector: matchLabels: component: dubbo-provider namespaceSelector: matchNames: - mall endpoints: - port: metrics path: /metrics interval: 30s这段配置告诉 Prometheus在mall这个命名空间里找出所有带component: dubbo-provider标签的 Service然后抓取它们名为metrics的端口。这里有个很容易被忽视的点ServiceMonitor 的selector匹配的是 Service 的标签不是 Pod 的标签。我把服务全都打上component: dubbo-provider而不是具体应用名就是为了让后续新增服务时能自动被监控覆盖。如果你用应用名做标签比如app: order-provider那每新增一个服务都要再写一个 ServiceMonitor维护成本立刻上来了。Prometheus 实例本身还要配置serviceMonitorSelector也就是只认带某些标签的 ServiceMonitor。这个机制相当于给监控对象做了一个白名单。假如你有多个团队共用同一个 Prometheus各团队自己维护的 ServiceMonitor 都会被采集除非通过命名空间隔离或标签隔离。我习惯在所有 ServiceMonitor 上打team标签再让 Prometheus 只选自己需要的那部分。3. Prometheus 与告警规则的一次性交付3.1 一个最小的 Prometheus 落地方案如果你的环境还没有 Prometheus我通常建议直接基于社区公开的 kube-prometheus-stack 来部署它能一次带来 Prometheus、AlertManager、Grafana 以及一堆 Kubernetes 基础监控规则。就交付 Dubbo 服务这个目标而言不需要从头写一堆 Operator只要保证最终有一个可用的 Prometheus 实例即可。部署完成后先确认 Prometheus 能访问 ServiceMonitor。假如 Prometheus 部署在monitoring命名空间ServiceMonitor 在mall命名空间则需要让 Prometheus 的serviceMonitorNamespaceSelector允许跨命名空间选择。这个配置我见过不少人漏掉表现就是 Prometheus 的 Targets 页面里一直没有任何 target而 ServiceMonitor 本身却明明被创建成功。一个最小可用的 Prometheus 自定义资源配置大概是这个样子apiVersion: monitoring.coreos.com/v1 kind: Prometheus metadata: name: prometheus namespace: monitoring spec: serviceAccountName: prometheus serviceMonitorSelector: matchLabels: team: delivery serviceMonitorNamespaceSelector: matchNames: - mall - monitoring resources: requests: memory: 2Gi limits: memory: 4Gi抓取策略里interval我建议不要设太短。Dubbo 接口级别的指标变化通常以秒为粒度30 秒一次已经足够。如果设成 5 秒一次几十个服务同时抓取Prometheus 自身的 CPU 和内存会涨得很快但带来的监控精度提升并不明显。资源有限的情况下宁可延长抓取间隔也要保证规则和查询性能稳定。3.2 告警规则怎么写才不“狼来了”写告警规则是最见功力的地方。规则写得太粗比如请求失败率超过 5% 就告警在低峰期可能根本触发不了高峰期又因为阈值过低疯狂报警。我一般按服务重要程度分层核心交易链路的接口告警阈值更严格周边服务的阈值放宽。还要注意告警表达式的分母。错误率计算必须用一段时间窗口内的错误请求数除以总请求数不能直接查瞬时值否则一次抖动就可能造成误报。以下是一个典型的 Dubbo 服务错误率告警规则示例apiVersion: monitoring.coreos.com/v1 kind: PrometheusRule metadata: name: dubbo-rules namespace: monitoring spec: groups: - name: dubbo-provider.rules rules: - alert: DubboProviderHighErrorRate expr: | sum(rate(dubbo_provider_requests_total{statuserror}[5m])) by (service, interface) / sum(rate(dubbo_provider_requests_total[5m])) by (service, interface) 0.05 for: 5m labels: severity: page annotations: summary: Dubbo provider {{ $labels.service }} error rate over 5% description: Interface {{ $labels.interface }} error rate exceeds threshold.注意dubbo_provider_requests_total这个指标名不一定和你们环境完全一致。不同 Dubbo 版本的指标命名存在差异我每次交付时都会先到/metrics端点确认一下实际指标名再套到规则里。拿一个不存在的指标写规则Prometheus 不会报错但规则永远不触发这类问题最难排查。告警表达式里for: 5m的含义是“持续五分钟才触发”。这个参数是抗抖动的关键。没有它一次瞬时网络抖动就会让告警轰炸你这个小时剩余时间。3.3 AlertManager 通知链路告警规则生成后最终要有人真正看到。AlertManager 支持邮件、企业微信、钉钉、Slack 和通用 Webhook。我习惯用 Webhook 中转因为告警既要发给运维群还要同步给相关开发一个通用 Webhook 比较灵活。AlertManager 的配置核心是路由。同一套规则的不同 severity应路由到不同接收人。比如severitypage的告警要立即通知值班群severitywarning只进入告警记录不打扰人。如果你把所有告警都捅给同一个群很快这个群就会被淹没真正重要的告警反而没人看。有一点值得提醒AlertManager 本身也是一个需要交付在 K8s 里的组件。如果部署的命名空间和应用不同要注意网络策略。否则规则触发后告警进不了 AlertManager排查时又得多绕一个弯。4. Grafana 面板把监控数字变成可读的业务信号4.1 数据源与看板配置Grafana 配数据源很简单重点在于数据源地址别写错。Prometheus 实例如果是通过 Operator 部署的通常会有一个名为prometheus-operated的 ServiceGrafana 的数据源地址应填这个 Service 的完整域名。我推荐用 Grafana Provisioning 来管理数据源和看板而不是每次都在页面上手工操作。Provisioning 的好处是可以把配置放进 Git整个监控交付随之可复现。一份数据源配置可以写成apiVersion: v1 kind: ConfigMap metadata: name: grafana-datasources namespace: monitoring data: datasources.yaml: | apiVersion: 1 datasources: - name: Prometheus type: prometheus access: proxy url: http://prometheus-operated.monitoring:9090看板的 JSON 也可以放进 ConfigMap配合 Grafana 的 dashboard sidecar 自动加载。如果你暂时不想折腾 Provisioning直接在 Grafana 页面导入 JSON 也能用只是后续变更要靠手动复制时间一长容易漂移。4.2 四个面板先安排上新交付的 Dubbo 监控我建议第一版 Grafana 只放四个面板不要贪多。第一个面板是 QPS按 Dubbo 接口维度展示每秒调用次数。这个面板能回答“当前服务是否真的有流量流量是否撑起来了”。第二个面板是延迟分布重点看 P99 和 P95。第三个面板是成功率按服务或接口聚合展示错误率。第四个面板是线程池活跃度这个最直观的展现就是 Dubbo 线程池 active count。对应查询表达式可以类似这样sum(rate(dubbo_provider_requests_total[1m])) by (interface)延迟 P99 的查询则是histogram_quantile(0.99, sum(rate(dubbo_provider_duration_milliseconds_bucket[5m])) by (le, interface) )面板里的时间范围我建议默认 6 小时不要设 1 小时否则告警来了想看趋势时数据量太少。另外给面板加一列“当前值 vs 昨天同期”这种对比比绝对值更能暴露出问题。5. 交付过程中常见的坑与排查思路5.1 最常见的问题速查我整理了一份自己交付时反复遇到的坑做成速查表供你对照现象可能原因排查动作Prometheus Targets 页面没有目标ServiceMonitor 没被 Prometheus 选中检查 Prometheus 的 serviceMonitorSelector 和 serviceMonitorNamespaceSelector目标显示 down端口号或路径不对进 Pod 执行 curl 访问 /metrics面板部分服务有数据、部分没数据Service 标签没匹配全确认 Service 的 labels 是否包含 ServiceMonitor selector 所需标签有指标但告警不触发指标名写错或阈值太高到 Prometheus 查询表达式看结果是否一直为 0告警总在半夜误报阈值没有按流量基线划分调高 for 时长或按 service 拆分规则Prometheus 内存涨得快抓取间隔太短、指标基数太大延长 interval排查是否需要减少高基数标签5.2 一套排查顺序值得背下来监控面板没数据的排查顺序我建议固定下来。按这个顺序走你很少会绕远路。先看 Prometheus 的 Targets 页面确认目标状态是 up 还是 down。如果是 down问题大概率出在采集配置如果目标根本不存在问题大概率出在 ServiceMonitor 匹配或注解。第二步直接进到 Pod 内部用curl访问指标地址验证应用确实已经把指标吐出来。第三步检查 Service 的标签和 ServiceMonitor 的 selector 是否对上这里最容易犯一个低级错误标签键写对了、值写错了。第四步查 Prometheus 的 serviceMonitorSelector确认它认这个 ServiceMonitor。最后再去 Grafana 里看面板查询是否有语法错误。这套顺序的核心逻辑是从“数据是否存在”到“数据是否被发现”再到“数据是否能查询”。跳过前两步直接改 Grafana 查询常常是在为一个不存在的数据源浪费时间。5.3 指标缺失时先分“采集问题”还是“指标源问题”接口级指标偶尔会丢一部分比如 80% 的服务有请求量数据剩下 20% 始终没有。遇到这种情况不要急着改全局配置。先在 Prometheus 里查询出确实有数据的服务再和缺数据的服务对照一般差异出在两类一类是采集问题比如某些 Pod 被调度到了没有网络能的节点或 Service 端口没有额外指定 metrics 端口。另一类是指标源问题比如这套服务用的 Dubbo 版本里部分接口没有开启 metrics exporter。我建议在交付时做一个小脚本遍历所有 provider 的 Pod逐一请求/metrics把返回结果记录下来。这样能够快速确认采集链路是否通了。否则你连“是应用没吐数据”还是“Prometheus 没抓到”都分不清排查就无从谈起。6. 影响范围监控“上线”后交付流程能跟着改什么监控交付完成后它不只是多了一个可视化工具而是直接影响后续整个交付工作的判断方式。首先是发布决策。以前我们靠“看起来还行”来判断服务是否可以放量现在可以直接看 QPS 和错误率曲线如果新版本上线后错误率没上升、P99 延迟没有明显变长就有底气继续推进下一步。相反如果看到一个接口的错误率在渐进上涨就要立刻回滚。其次是容量规划。Dubbo 服务在 K8s 上扩容很容易问题是什么时候扩。以前等到用户投诉才发现线程池打满现在通过线程池活跃数、请求排队时长可以在流量还没完全进入之前预判资源缺口。第三是跨团队协作。接口级监控数据和告警一旦接入统一告警平台业务研发、运维、平台三方看的是同一套指标。告警发生时责任边界更清晰不需要反复截图解释“这个指标是什么意思”。从交付视角看监控不应该排在所有服务上线之后而应该作为交付的最后一道验收关卡。服务上线不代表交付完成监控数据和告警链路都验证通过才是一个可交付的状态。最后聊一点个人体会。我刚开始做这类交付时最常犯的毛病是总想一次性把所有面板、所有告警、所有服务都配齐结果配置一多哪里出错都看不出来。后来我养成一个习惯每次交付只先接通一个服务的完整链路从 metrics 到 Prometheus 再到 Grafana 面板全部验证通过后再批量铺开。这个笨办法看着慢实际上最稳。毕竟监控这个东西一旦没配好它不像业务漏洞那么容易暴露等到真出问题时你会发现你看不见问题那才是真正的问题。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询