
1. 项目概述这不是一次“部署上线”而是一场从实验室到产线的系统性迁移“From Notebook to Production: Running ML in the Real World (Part 4)”——这个标题里藏着太多被新手忽略的潜台词。它不是教你怎么把model.fit()跑通也不是演示如何用Flask搭个API接口就喊“上线成功”。它直指一个残酷现实你在Jupyter里调出98.7%准确率的模型和它在凌晨三点扛住电商大促流量、持续输出稳定预测、自动熔断异常输入、日志可追溯、版本可回滚、资源不越界、监控有告警——这中间隔着的不是几行代码而是一整套工程化认知体系。我带过二十多个落地项目亲眼见过太多团队卡在Part 4模型在测试环境跑得飞起一上生产就内存爆满、延迟飙升、特征漂移无声无息、AB测试结果无法归因。Part 4的本质是把“能跑”变成“敢用”把“实验产物”变成“业务资产”。它覆盖的不是某个工具链而是数据流、模型流、服务流、反馈流四条主干道的协同治理。关键词里的ML in the Real World核心不在“ML”而在“Real World”——真实世界意味着不确定性、时变性、协作复杂性和成本刚性。你不需要成为Kubernetes专家但必须清楚模型容器化后CPU限制设为2核还是4核会直接决定单实例吞吐量是30 QPS还是120 QPS你不必手写Prometheus exporter但得明白为什么model_prediction_latency_seconds_bucket这个指标比accuracy更能反映线上健康度。这篇文章面向的是已经能把模型训出来的工程师、数据科学家以及那些正被“为什么上线后效果掉点”“为什么运维总说我们服务不稳定”“为什么AB测试结论打架”这些问题反复捶打的技术负责人。它不提供银弹但给你一套可验证、可裁剪、已在金融风控、智能客服、工业质检等场景反复打磨过的落地检查清单。2. 内容整体设计与思路拆解为什么Part 4必须聚焦“可观测性弹性反馈闭环”三位一体2.1 拒绝“一次性部署思维”真实世界的模型是活的不是标本很多团队的Part 4实践本质是把Notebook导出为Python脚本再用Gunicorn包一层扔进Docker跑起来。这看似完成了“部署”实则埋下三颗定时炸弹第一状态不可知——你不知道模型当前每秒处理多少请求、平均延迟多少、失败率几何、特征分布是否偏移第二弹性不可控——流量高峰时实例自动扩缩容策略缺失要么资源闲置浪费要么雪崩式宕机第三进化不可持续——线上预测结果没有反哺训练数据模型像离线孤岛越用越老。我参与过一个推荐系统迁移初期采用纯静态部署结果双十一大促期间因未配置水平扩缩容HPA单实例CPU打满至98%P99延迟从200ms飙到2.3秒用户点击率直接跌了17%。复盘发现问题根源不在模型本身而在整个服务架构缺乏对“真实流量脉搏”的感知与响应能力。因此Part 4的设计起点必须从“让模型跑起来”转向“让模型在变化中稳住并进化”。这决定了我们技术选型的底层逻辑所有工具链必须服务于三个核心目标——可观测性Observability、弹性Resilience Scalability、反馈闭环Feedback Loop。它们不是并列选项而是环环相扣的铁三角可观测性提供决策依据弹性保障服务底线反馈闭环驱动持续优化。放弃其中任一环Part 4就只是半成品。2.2 工具链选型逻辑不追新只求“够用、可控、可审计”在Kubeflow、Seldon、KServe、MLflow、BentoML这些名词满天飞的时代Part 4最危险的陷阱就是陷入“工具军备竞赛”。我见过团队花三个月集成Kubeflow Pipelines结果连基础的模型版本灰度发布都没跑通因为其抽象层过于厚重调试链路长达十几层。真实产线要的是“确定性”而非“先进性”。我们的选型原则非常朴素可观测性层放弃自研Metrics Collector直接采用OpenTelemetry SDK Prometheus Grafana黄金组合。理由很实在OpenTelemetry是CNCF毕业项目SDK侵入式埋点代码仅需5行且社区插件覆盖Flask/FastAPI/Triton等所有主流框架Prometheus的Pull模型天然适配容器化环境Grafana仪表盘模板社区超2000个金融客户要求的“预测延迟分位图特征统计热力图”半小时就能搭出来。弹性服务层不碰Knative或KEDA这类复杂事件驱动方案首选Kubernetes原生HPAHorizontal Pod Autoscaler 自定义指标如基于http_requests_total或model_inference_duration_seconds_sum。实测表明HPA配合Prometheus Adapter从CPU阈值触发到新Pod Ready平均耗时47秒完全满足电商类业务分钟级弹性需求而Knative的冷启动问题在实时性要求高的场景如风控决策会导致不可接受的首请求延迟。反馈闭环层拒绝重造数据管道轮子。直接用Apache Kafka作为预测结果与原始特征的统一消息总线下游接Flink做实时特征计算如“用户近10分钟点击率”同时用Debezium捕获业务库变更通过CDCChange Data Capture将用户行为事件如购买、退款实时注入训练数据湖。这套组合的优势在于所有组件均为成熟数据领域基础设施运维团队已有知识储备故障排查路径清晰——Kafka lag高查消费者组Flink任务背压看反压指标Debezium连接中断看MySQL binlog position。这种“用熟不用生”的策略让Part 4的落地周期从预估6个月压缩到11周且上线后首个季度无P1级故障。2.3 架构演进路径从“单体服务”到“领域驱动服务化”的必然选择Part 4的终极形态绝非一个巨石型ML服务。我们观察到所有成功跨越Part 4的团队最终都走向了按业务域拆分的微服务架构。以某保险公司的车险定价模型为例初期所有逻辑特征工程、模型推理、规则引擎、报价生成打包在一个FastAPI服务里。上线后很快暴露问题——精算师要调整折旧率计算规则需全量回归测试AI团队升级XGBoost到LightGBM却因特征预处理代码耦合导致报价金额偏差超0.5%。后来我们按DDD领域驱动设计思想重构特征服务Feature Serving独立服务提供/features?entity_idcar_123as_of2024-05-20接口所有模型消费同一份实时特征模型服务Model Serving仅负责加载模型、执行predict()输入为标准化特征向量输出为原始分数决策服务Decision Service聚合模型分数、业务规则、外部数据如天气API生成最终报价与风险等级。这种拆分带来质变特征服务由数据平台团队统一维护保证全公司特征一致性模型服务由AI团队独立迭代A/B测试可精确到单个模型版本决策服务由业务方掌控规则变更无需AI团队介入。更重要的是可观测性指标得以精准归因——当发现报价延迟升高可快速定位是特征服务DB查询慢feature_db_query_duration指标飙升还是模型服务GPU显存不足gpu_memory_utilization达95%而非在单体服务里大海捞针。Part 4的深度就体现在这种对业务复杂性的尊重与解耦能力上。3. 核心细节解析与实操要点从代码到产线的12个关键断点检查3.1 断点1特征一致性——Notebook与生产环境的“特征鸿沟”如何填平这是Part 4里最高频、最隐蔽的坑。你在Notebook里用pandas.read_csv(data.csv)读取数据sklearn.preprocessing.StandardScaler().fit_transform(X)做标准化一切完美。但生产环境里特征工程代码若未封装为可复用函数或未与训练时使用完全相同的StandardScaler对象含mean/std参数就会导致输入特征分布偏移模型效果断崖下跌。我们强制推行“特征工厂Feature Factory”模式所有特征处理逻辑必须定义在独立Python模块如features/vehicle_features.py中并通过joblib.dump(scaler, scaler.joblib)持久化训练时的转换器。生产服务加载模型时同步加载对应scaler.joblib。更进一步我们要求每个特征函数必须带version参数例如def calc_vehicle_age(entity_id: str, as_of_date: datetime, version: str v1) - float: if version v1: # 原始逻辑注册日期到as_of_date的年数 return (as_of_date - get_reg_date(entity_id)).days / 365.25 elif version v2: # 新逻辑引入车辆使用强度修正因子 base_age (as_of_date - get_reg_date(entity_id)).days / 365.25 intensity get_usage_intensity(entity_id) return base_age * (1 0.2 * intensity) # v2新增这样当精算师提出新特征逻辑只需新增versionv2分支旧模型继续用v1新模型指定v2避免全量切换风险。 提示务必在CI/CD流水线中加入“特征一致性校验”步骤——用相同输入数据对比Notebook导出的特征向量与生产服务返回的特征向量逐元素比对差异超过1e-6即阻断发布。3.2 断点2模型序列化——Pickle的甜蜜陷阱与安全替代方案joblib.dump(model, model.pkl)是Notebook里的惯用操作但它在生产环境是颗雷。Pickle协议存在严重安全隐患反序列化任意二进制数据可执行任意代码且不同Python版本、不同scikit-learn版本间Pickle文件不兼容曾导致某客户因服务器升级Python 3.8→3.9所有模型加载失败服务瘫痪2小时。我们的硬性规定禁止在生产环境使用Pickle序列化模型。替代方案分三层轻量级模型10MB用ONNXOpen Neural Network Exchange格式。XGBoost/LightGBM/Scikit-learn均支持model.export_model(formatonnx)ONNX Runtime推理速度比原生Python快3-5倍且跨语言、跨平台、无代码执行风险。深度学习模型TensorFlow SavedModel或PyTorch TorchScript。前者支持TensorFlow Serving后者经torch.jit.script(model)编译后可脱离Python解释器运行内存占用降低40%。超大模型1GB采用模型分片Model Sharding 参数服务器Parameter Server架构。例如将BERT-large的1000万参数按层切分每个gRPC服务实例只加载部分层通过model_layer_1:50051、model_layer_2:50052等地址协同推理。这虽增加网络开销但规避了单机内存瓶颈某NLP项目实测分片后单节点内存从24GB降至8GB集群可用性提升至99.99%。3.3 断点3服务接口设计——REST vs gRPC别让通信协议拖垮你的P99延迟很多团队默认用Flask/FastAPI提供RESTful API这在低QPS场景没问题但当QPS超500、模型输入为高维向量如1024维Embedding时JSON序列化/反序列化开销会吃掉30%以上延迟。我们做过对比测试对同一LightGBM模型输入128维特征分别用FastAPI REST和gRPC提供服务指标FastAPI (REST)gRPC (Protobuf)P50延迟18ms9msP99延迟42ms15ms单实例吞吐850 QPS2100 QPS网络带宽占用1.2MB/s0.3MB/s差距源于Protobuf的二进制编码效率远高于JSON。但gRPC并非银弹——它要求客户端和服务端强契约.proto文件调试不如REST直观。我们的折中方案对外提供REST API供前端、低频调用方使用对内微服务间通信强制使用gRPC。例如决策服务调用模型服务时走gRPC而APP端调用决策服务仍用HTTPS REST。这样既保障了内部性能又维持了对外兼容性。 注意gRPC服务必须配置max_message_length否则大尺寸特征向量如图像Embedding会被截断。我们默认设为100 * 1024 * 1024100MB并在客户端做分块上传校验。3.4 断点4资源隔离——为什么你的模型服务总在OOM Killer下“猝死”Kubernetes里不设resources.limits等于给模型服务发了一张“无限透支信用卡”。某次上线一个未限制内存的LSTM模型服务在处理长文本序列时因PyTorch缓存机制内存从2GB一路涨到16GB触发Linux OOM Killer进程被粗暴杀死服务雪崩。正确姿势是为每个容器设置精确的requests和limits。计算方法如下内存Memory在测试环境用psutil.Process().memory_info().rss监控模型加载后、空载时的常驻内存RSS再模拟峰值QPS压力记录最大RSS。取两者较大值乘以1.3冗余系数。例如空载RSS1.2GB峰值RSS2.8GB →requests2.8Gi, limits3.6Gi。CPU用time命令测量单次推理耗时结合目标QPS计算理论CPU需求。例如单次推理耗时150ms目标QPS100 → 每秒需15秒CPU时间 → 理论需15核。但实际需考虑上下文切换、I/O等待我们按理论值 × 1.5设requestslimits设为requests × 2。故requests22.5, limits45单位mCPU即22500m。实操心得limits设得太低容器会被OOM Killer杀设得太高K8s调度器无法有效利用节点资源。我们坚持“宁紧勿松”通过HPA动态扩缩容来应对流量波动而非靠单实例硬扛。3.5 断点5健康探针——Liveness与Readiness探针的生死线K8s的livenessProbe和readinessProbe是服务稳定的基石但90%的团队配置错误。常见错误用/healthz端点做Liveness该端点只检查进程存活不验证模型能否真正推理。结果服务进程活着但模型因GPU显存不足卡死K8s却认为健康持续转发流量导致大量超时。Readiness探针超时时间过短设为timeoutSeconds1而模型首次加载需3秒如BERT加载词表Pod永远无法进入Ready状态。我们的标准配置livenessProbe: httpGet: path: /healthz/live port: 8000 initialDelaySeconds: 60 # 给足模型加载时间 periodSeconds: 30 # 每30秒检查一次 timeoutSeconds: 5 # 超时5秒即判为不健康 readinessProbe: httpGet: path: /healthz/ready port: 8000 initialDelaySeconds: 120 # 首次就绪检查延后2分钟 periodSeconds: 10 # 每10秒检查一次 timeoutSeconds: 3 # 就绪检查更严格关键在/healthz/live和/healthz/ready的实现逻辑live端点仅检查进程、端口、基础依赖如Redis连接不涉及模型ready端点必须执行一次真实推理如用预置的test_sample.json调用predict()并验证返回码、延迟500ms、结果合理性如分数在[0,1]区间。只有ready通过K8s才将Pod加入Service Endpoints接收真实流量。这确保了“能接流量”即“真能干活”。3.6 断点6日志规范——为什么你的日志在故障时“查无可查”Notebook里print(Predicting...)的随意日志在生产环境是灾难。我们强制推行结构化日志Structured Logging所有日志必须是JSON格式包含固定字段。例如一次预测请求的日志{ timestamp: 2024-05-20T08:30:45.123Z, level: INFO, service: model-service, version: 1.2.4, request_id: req_abc123, model_name: fraud_xgb_v3, input_features: {age: 35, income: 85000, trans_count_24h: 12}, prediction_score: 0.872, inference_latency_ms: 42.5, status: success }关键设计request_id贯穿全链路从API网关生成经特征服务、模型服务、决策服务所有日志携带同一ID故障时可一键串联完整调用链input_features采样记录非全量记录防隐私泄露而是按feature_sampling_rate0.01随机采样1%请求的特征用于事后分析特征漂移status字段驱动告警ELK或Loki中设置告警规则——status: error且inference_latency_ms 1000连续5次即触发P1告警。注意日志级别要克制。DEBUG日志仅在开发环境开启生产环境默认INFOERROR必须包含可操作的根因提示如ERROR: Failed to load model from s3://bucket/model.onnx: ConnectionTimeout (15s)而非模糊的Model load failed。3.7 断点7监控指标——别再只盯着AccuracyP99延迟才是生命线Accuracy、F1-score是训练阶段的“成绩单”线上监控必须切换到“服务健康度”视角。我们定义核心SLOService Level Objective指标可用性Availability1 - (sum(rate(http_request_total{status~5..}[1h])) / sum(rate(http_request_total[1h]))) 0.9995延迟Latencyhistogram_quantile(0.99, rate(model_inference_duration_seconds_bucket[1h])) 200P99延迟200ms饱和度Saturationcontainer_memory_usage_bytes{containermodel-service} / container_spec_memory_limit_bytes 0.85内存使用率85%即预警。特别强调model_inference_duration_seconds_bucket——这是模型服务专属指标必须在代码中手动埋点from prometheus_client import Histogram INFERENCE_DURATION Histogram( model_inference_duration_seconds, Model inference duration in seconds, buckets(0.01, 0.025, 0.05, 0.1, 0.2, 0.5, 1.0, 2.0, 5.0) ) # 在predict()函数内 with INFERENCE_DURATION.time(): result model.predict(input_data)这样Grafana就能绘制出延迟分布直方图一眼看出是“大部分快、个别极慢”需查异常样本还是“整体缓慢”需优化模型或硬件。 实操心得不要迷信单一P99。我们同时监控P50/P90/P99若P5050ms、P9080ms、P991500ms说明存在长尾毛刺应重点分析那1%的慢请求而非盲目升级CPU。3.8 断点8配置管理——为什么你的“小修改”总引发线上事故config.yaml硬编码在代码仓库每次改阈值都要发版这是Part 4的大忌。我们采用“配置中心环境隔离”方案配置中心选用Apollo国内企业主流或Consul海外常用所有配置项如model_version,feature_timeout_ms,ab_test_ratio集中管理环境隔离dev/staging/prod三套命名空间prod环境配置变更需双人复核灰度发布热更新服务监听配置变更事件无需重启即可生效。例如当ab_test_ratio从0.0全量旧模型改为0.110%流量切新模型服务自动加载新分流策略。关键实践所有配置项必须带类型声明与校验。Apollo中定义feature_timeout_ms为Integer类型范围[100, 5000]超出即拒绝提交。这避免了1000字符串被误解析为1000整数或50000毫秒50秒超时导致级联故障。3.9 断点9AB测试——如何科学归因而非“玄学对比”很多团队的AB测试只是把新旧模型各挂一个Endpoint用Nginx 50/50分流然后看“转化率”数字。这忽略了混杂变量新模型上线时段恰逢周末旧模型在工作日结果差异根本无法归因于模型。我们强制要求流量分桶Traffic Splitting基于user_id哈希而非简单轮询。hash(user_id) % 1000-49为A组旧模型50-99为B组新模型。确保同一用户始终看到同一模型结果消除用户行为波动干扰指标对齐Metric AlignmentAB测试必须定义核心指标Primary Metric与护栏指标Guardrail Metrics。例如推荐系统核心指标是“7日留存率”护栏指标是“单日PV”“平均停留时长”。若新模型提升留存率但PV下降10%说明可能过度激进需叫停统计显著性Statistical Significance必须达到p-value 0.05且minimum detectable effect (MDE)在业务可接受范围内如留存率提升0.5%。我们用statsmodels.stats.proportion.proportions_ztest实时计算Dashboard上红绿灯显示显著性状态。注意AB测试周期不能太短。我们要求最小样本量满足n (Z_{α/2} Z_β)^2 * p*(1-p) / δ^2其中p为基线转化率δ为MDE。某次测试因仅跑48小时样本不足得出“新模型差”的错误结论返工重测耗时两周。3.10 断点10模型漂移检测——你的模型正在“悄悄变老”你却浑然不觉模型上线后数据分布随时间推移而变化Data Drift是效果衰减的主因。某信贷模型上线3个月后审批通过率从65%降至52%起初以为是经济下行后经漂移检测发现用户年龄中位数从38岁升至45岁而模型在45岁以上人群的AUC仅0.61训练集为0.82。我们构建三级漂移检测体系一级实时对每个数值型特征计算在线滑动窗口1小时的均值、标准差与基线训练集对比偏离超3σ即告警二级小时级用KS检验Kolmogorov-Smirnov Test比较线上特征分布与训练分布p-value 0.01即触发三级天级用PCA降维后计算线上样本在训练样本主成分空间的投影距离距离突增表明整体分布偏移。所有检测结果写入drift_alerts表与Grafana联动。当age特征KS检验p-value跌破0.01仪表盘自动标红并推送企业微信告警“用户年龄分布发生显著漂移请核查数据采集逻辑或启动模型重训”。3.11 断点11回滚机制——当新模型翻车你能在5分钟内回到“昨天”吗“回滚”不是一句口号而是需要提前设计的逃生通道。我们要求模型版本原子化每个模型版本如fraud_xgb_v4对应独立S3路径、独立Docker镜像Tag、独立K8s Deployment YAML蓝绿部署Blue-Green新版本部署为greenDeployment流量先切5%验证无异常后切100%旧blueDeployment保留24小时一键回滚脚本rollback.sh脚本自动执行1) 将Service流量切回blue2) 删除greenDeployment3) 清理green相关ConfigMap/Secret。实测从发现故障到回滚完成耗时3分42秒。关键经验回滚后必须验证“状态一致性”。例如风控模型回滚需确认decision_log表中model_version字段已全部回退而非仅服务流量切换。我们为此开发了post-rollback-checker自动比对数据库记录与服务版本。3.12 断点12安全合规——GDPR、等保2.0不是纸面功夫模型服务处理用户数据安全合规是红线。我们落地三项硬措施数据脱敏Data Sanitization所有日志、监控、采样数据中的PIIPersonally Identifiable Information字段如id_card,phone必须在入口处sha256()哈希且哈希盐值定期轮换模型水印Model Watermarking在训练数据中嵌入微小扰动如对1%样本的某特征加1e-5噪声使模型输出带有唯一指纹。若发现模型被非法复制可通过输出反推水印法律维权有据等保2.0适配所有服务容器启用seccomp安全策略禁用chmod、chown等危险系统调用网络策略NetworkPolicy严格限制Pod间通信模型服务仅允许来自API网关和特征服务的入站流量。某次等保测评因未启用seccomp被判定为“高风险项”整改耗时一周。自此我们把安全检查纳入CI/CD流水线docker scan和kube-bench扫描不通过自动阻断镜像推送。4. 实操过程与核心环节实现以电商实时推荐模型上线为例的全流程拆解4.1 场景设定从Notebook原型到支撑双11的推荐服务我们以某电商平台“猜你喜欢”实时推荐模型为案例完整走一遍Part 4落地。该模型目标根据用户实时行为点击、加购、搜索在500ms内返回个性化商品列表P99延迟≤300ms日均调用量2.4亿次。Notebook原型已用LightGBM训练完成AUC0.89特征包括用户画像年龄、性别、地域、近期行为序列最近10次点击商品ID的Embedding均值、实时上下文当前搜索词TF-IDF。现在我们要把它变成生产服务。4.2 步骤1特征服务化——构建统一、实时、可复用的特征工厂第一步不是碰模型而是解耦特征。我们将所有特征计算逻辑抽离创建feature-service项目特征注册在features/catalog.py中定义FEATURES { user_age_embedding: { type: numerical, source: mysql://user_profile, transform: lambda x: [x[age]/100, x[gender_int]], ttl_seconds: 86400 # 缓存1天 }, recent_clicks_mean_emb: { type: embedding, source: kafka://click_stream, transform: lambda clicks: np.mean([get_item_emb(c) for c in clicks[-10:]], axis0), ttl_seconds: 300 # 实时特征缓存5分钟 } }特征API用FastAPI实现/features端点输入{user_id: u123, as_of: 2024-05-20T08:00:00Z}返回标准化特征向量。关键优化对user_age_embedding用Redis缓存MySQL查询结果GET user_profile:u123命中率92%P99延迟从85ms降至12ms对recent_clicks_mean_emb用Flink实时计算用户点击流结果存入Redis HashHGETALL user_clicks:u123避免Kafka消费延迟。特征一致性测试CI流水线中用pytest跑test_feature_consistency.py对比Notebook中calc_features(user_idu123)与feature-service返回结果误差1e-5即失败。4.3 步骤2模型服务化——ONNX Runtime gRPC的极致性能模型服务model-service采用ONNX Runtime加速模型导出Notebook中lgb_model.export_model(formatonnx, export_typedict)生成recommend.onnx服务框架用onnxruntime-serverC版而非Python版内存占用降低60%P99延迟从210ms降至85msgRPC接口定义recommend.protomessage PredictRequest { string user_id 1; repeated float features 2; // 特征向量 } message PredictResponse { repeated int32 item_ids 1; // 推荐商品ID列表 repeated float scores 2; // 对应分数 }资源配置K8s Deployment中设resources: {requests: {cpu: 2000m, memory: 4Gi}, limits: {cpu: 4000m, memory: 6Gi}}HPA基于grpc_server_handled_total{servicemodel-service}指标扩缩容。4.4 步骤3决策服务化——整合模型、规则与业务逻辑decision-service是业务大脑输入调用feature-service获取特征调用model-service获取原始分数规则引擎集成Drools配置业务规则如“新用户注册7天推荐商品池扩大20%”、“高价值用户VIP等级≥3屏蔽低价商品”重排序Re-ranking对模型输出的Top100商品用轻量级规则如库存0、价格区间匹配二次过滤再按score * stock_weight重排AB测试分流基于user_id哈希hash(user_id) % 100 10走新模型recommend_v2.onnx其余走v1。4.5 步骤4可观测性基建——从“黑盒”到“玻璃盒子”部署后立即接入可观测性三件套Metrics在model-service中埋点model_inference_duration_seconds_bucket在decision-service中埋点decision_latency_seconds_bucketTracing用Jaegeruser_id作为Trace ID串联API Gateway → decision-service → feature-service → model-service全链路Logging所有服务输出JSON日志request_id贯穿全程。Grafana Dashboard配置主面板P99延迟趋势model/decision/feature分层下钻面板当model延迟飙升查看onnx_runtime_execution_time子指标定位是CPU瓶颈还是GPU显存不足告警面板rate(http_request_total{status~5..}[5m])