工业网关 Metrics 暴露实战Counter、Gauge、Histogram 怎么选PromQL 怎么用工业网关一旦进到现场大家最先遇到的麻烦通常不是“功能不能跑”而是“出了问题看不见”。请求量上来了不知道重连频繁了不知道某个协议链路延迟突然抖动了也不知道。很多团队把日志当作唯一入口但日志更适合排查具体问题metrics才是长期观测系统状态的基础。这篇文章不讲抽象定义直接从工业网关常见场景出发把 4 类核心指标、/metrics暴露方式、标签设计和 PromQL 查询一起梳理清楚。一、工业网关为什么一定要做 metrics工业网关的运行环境有几个典型特点设备数量多单台问题很容易被淹没协议类型杂链路状态变化频繁现场网络不稳定异常经常是间歇性的运维要看趋势不只是看某一次报错这类场景下如果只有日志会出现两个问题只能“出了事再翻日志”很难快速回答“最近 5 分钟到底变差了没有”而metrics的价值就在于把系统状态量化出来让 Prometheus、Grafana、告警规则都能接上。二、先把 4 类指标分清楚1. Counter适合累计事件只增不减。常见场景HTTP 请求总数协议重连次数上报失败次数告警触发次数fromprometheus_clientimportCounter requests_totalCounter(http_requests_total,Total HTTP requests,[method,path,status])app.middleware(http)asyncdefcount_requests(request,call_next):responseawaitcall_next(request)requests_total.labels(methodrequest.method,pathrequest.url.path,statusresponse.status_code,).inc()returnresponse如果你要看“速率”不是直接看原始值而是配合rate()或increase()。2. Gauge适合瞬时状态可增可减。常见场景当前在线连接数队列长度内存占用正在处理中的任务数fromprometheus_clientimportGauge connections_activeGauge(connections_active,Active connections,[protocol])asyncdefon_connect(conn):connections_active.labels(protocolconn.protocol).inc()asyncdefon_disconnect(conn):connections_active.labels(protocolconn.protocol).dec()Gauge 很适合“现在系统长什么样”但不适合直接表达累计事件。3. Histogram适合统计分布尤其适合延迟类指标。常见场景HTTP 请求耗时轮询采集耗时消息处理耗时下发命令往返时延fromprometheus_clientimportHistogram request_durationHistogram(http_request_duration_seconds,HTTP request duration,[method,path],buckets[0.005,0.01,0.025,0.05,0.1,0.25,0.5,1,2.5,5,10])app.middleware(http)asyncdeftime_requests(request,call_next):withrequest_duration.labels(methodrequest.method,pathrequest.url.path,).time():returnawaitcall_next(request)Histogram 的价值不只是能看平均值更重要的是它能做 P95、P99 这类分位统计。4. SummarySummary 也能做分位数但在 Prometheus 生态里跨实例聚合往往不如 Histogram 顺手。只要你的指标要做统一查询和告警Histogram 通常更稳。三、/metrics暴露本身并不复杂很多 Python 网关服务直接挂一个指标端点就够了fromprometheus_clientimportmake_asgi_app metrics_appmake_asgi_app()app.mount(/metrics,metrics_app)Prometheus 侧再做抓取scrape_configs:-job_name:edge-gatewayscrape_interval:15sstatic_configs:-targets:-gateway-1:8080-gateway-2:8080-gateway-3:8080现场规模一大后面还会继续演进到服务发现、实例标签、区域标签但第一步一定是先把端点暴露标准化。四、真正容易踩坑的是标签设计同一条指标标签设计对了Prometheus 很稳标签设计错了内存和查询性能都会被拖垮。低基数标签通常是合理的比如methodpathstatusprotocolsite下面这种高基数标签现场项目里要尽量避免直接挂上去user_idrequest_idsession_id完整设备序列号动态变化且种类巨多的原始错误消息# 推荐低基数标签requests_totalCounter(http_requests_total,Total HTTP requests,[method,path,status])# 不推荐高基数标签requests_totalCounter(http_requests_total,Total HTTP requests,[user_id,request_id])一句话总结能不能聚合、会不会无限膨胀是标签设计时最该先想的事。五、PromQL 才决定这些指标能不能真正用起来几个最常用的查询基本够支撑第一版面板和告警rate(http_requests_total[5m])sum(rate(http_requests_total{status~5..}[5m])) / sum(rate(http_requests_total[5m]))histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[5m])) by (le) )topk(10, sum by (path) (rate(http_requests_total[5m])))工业网关项目里我通常会先把 RED 和 USE 两套思路拼起来RED 看请求量、错误率、耗时USE 看资源利用率、饱和度、错误这样服务侧和资源侧会更完整。六、几个工程上最常见的坑1. 命名不统一今天叫_total明天叫_count后面面板和规则就会越来越乱。建议一开始就统一事件类用_total耗时类用_seconds。2. 标签高基数这是最容易把 Prometheus 打疼的问题。只要标签值数量会快速膨胀就要重新设计。3. Histogram bucket 乱给Bucket 不是越多越好也不是默认值一定适合。要根据你的业务耗时分布来定比如是毫秒级接口还是秒级链路。4. 只暴露指标不做查询和面板没有查询、没有面板、没有告警的 metrics最后只会变成没人看的数据堆。5. 版本演进没人管指标一旦被外部面板和告警依赖后续改名、删标签、改语义都要有变更约束。七、结论工业网关做 metrics 暴露不是简单把几个 Counter 往代码里一塞就结束了。真正决定系统可观测性质量的是 4 件事指标类型选得对不对/metrics暴露是否标准标签基数有没有被控住PromQL、Grafana、告警链路有没有接起来如果你现在正准备给工业网关补监测建议最先做的是这 3 步先把请求数、错误数、连接数、耗时这几类核心指标补齐给标签做一次低基数检查用 PromQL 把速率、错误率和 P99 延迟先跑通这套基础打稳后后面的面板、告警和趋势分析才有意义。