首页 / 资讯中心 / 文章详情

AI工程从零构建:五层契约驱动的可交付AI系统

AI工程从零构建:五层契约驱动的可交付AI系统 ★ FEATURED ARTICLE
1. 这不是“搭积木”而是亲手锻造AI系统的完整工程链“AI Engineering from Scratch”——这个标题乍看像一句技术口号实则是一条被严重低估的硬核路径。过去三年我带过27个团队落地AI项目从智能客服到工业缺陷识别从医疗影像辅助标注到供应链需求预测几乎覆盖所有主流垂直场景。但凡用过现成平台比如某云AI Studio、某厂Model Studio、某开源低代码训练平台的团队83%在第六个月开始遭遇瓶颈模型迭代卡在数据管道里出不来上线服务响应延迟突然翻倍AB测试结果无法复现运维日志里堆满“OOM”和“CUDA out of memory”。问题从来不在算法本身而在于没人真正理解——那个被封装成“一键训练”的黑盒底层到底由多少个可调试、可监控、可替换的齿轮咬合而成。这正是“from scratch”的真实含义不是从零写Transformer而是从零构建一个可解释、可追踪、可灰度、可回滚的AI交付流水线。它包含五个不可跳过的工程层数据契约层Data Contract→ 特征工厂层Feature Factory→ 模型编排层Model Orchestration→ 服务契约层Serving Contract→ 观测闭环层Observability Loop。每一层都必须有明确的输入/输出定义、版本控制策略、失败熔断机制和人工干预入口。我见过太多团队把“feature store”当成数据库来用把“model registry”当成文件夹来存结果上线后发现特征偏移检测失效、模型热更新引发API协议错乱、线上推理耗时波动超过±400ms却查不到根源。适合谁读如果你是刚带AI团队的技术负责人正为“为什么模型效果好但业务指标没提升”发愁如果你是资深MLOps工程师厌倦了天天修pipeline脚本却说不清SLA保障逻辑如果你是算法研究员想摆脱“调参侠”标签真正参与产品级AI系统设计——这篇就是为你写的。它不讲PyTorch基础不教如何调learning rate而是带你一砖一瓦垒起整座AI工厂的地基、承重墙和通风系统。下面所有内容全部来自我们2023年为某新能源车企搭建电池健康预测系统的真实工程记录所有配置、参数、命令、报错截图均脱敏后保留原始结构。2. 为什么必须放弃“平台即一切”的幻觉从三个血泪案例看工程断层2.1 案例一特征漂移无声吞噬92%的模型价值某零售客户部署了销量预测模型初期MAPE 8.3%三个月后飙升至24.7%。平台监控只显示“预测误差上升”但没人知道原因。我们介入后在特征工厂层加装了双向特征指纹校验训练时对每个特征生成SHA256摘要含值分布、缺失率、极值范围上线时实时比对。结果发现上游ERP系统升级后last_7d_avg_order_amount字段的空值填充逻辑从“前向填充”改为“零填充”导致该特征在训练集和生产环境的分布KL散度达0.870.3即触发告警。平台本身不校验特征语义一致性只校验字段名存在——这就是典型的“工程断层”数据契约层缺失特征工厂层无校验观测层无溯源能力。提示特征指纹不能只算数值摘要。我们要求每个特征必须附带三元组(schema_type, statistical_profile, business_rule)。例如customer_age字段schema_typeINT32statistical_profile{min:18, max:85, std:12.3}business_rulemust be 0 and 100。任何一项不匹配即阻断上线。2.2 案例二模型编排层缺失导致灰度发布形同虚设某金融风控模型升级按平台文档执行“5%流量灰度”。结果上线12分钟后核心支付通道成功率下跌17%。排查发现平台所谓的“灰度”只是路由层分流但模型服务容器未做资源隔离——新旧模型共享同一GPU显存池当新模型加载更大embedding层时旧模型因OOM被K8s强制驱逐导致5%流量实际打到降级规则上。真正的灰度必须在模型编排层实现资源契约每个模型版本绑定独立的CPU/GPU配额、内存限制、网络QoS策略并通过eBPF注入实时监控其资源消耗曲线。我们后来在编排层强制要求resource_contract.yaml必须包含gpu_memory_mb: 24576、cpu_quota: 4000m、network_bandwidth_kbps: 12000三项硬约束否则CI流水线直接拒绝合并。2.3 案例三服务契约层裸奔引发全站级雪崩某内容平台上线推荐模型v3接口响应P99从120ms升至2.3s。平台监控只显示“latency increase”但无法定位是模型推理慢、还是序列化慢、或是下游缓存穿透。根本原因是服务契约层缺失没有明确定义/recommend接口的协议契约Protocol Contract和性能契约Performance Contract。协议契约规定请求体必须含user_context字段含设备类型、网络状态、历史行为ID响应体必须含trace_id和model_version性能契约则要求P99≤150ms超时自动降级至v2并上报。我们重构后在API网关层植入契约验证中间件若请求缺失user_context返回400并记录审计日志若响应超时自动切换v2且将v3的trace_id注入降级日志实现故障秒级归因。这三个案例共同指向一个事实AI工程不是算法平台的简单叠加而是五层契约的精密咬合。跳过任何一层都会在业务规模扩大后暴露为系统性风险。所谓“from scratch”本质是重建这五层之间的责任边界与协作协议。3. 五层工程架构详解从数据契约到观测闭环的实操落地3.1 数据契约层用Schema-as-Code定义数据可信边界数据契约不是Excel表格而是可执行、可测试、可版本化的代码合约。我们采用Great Expectations Pydantic Schema双轨制Pydantic Schema定义静态契约每个数据源对应一个data_contract.py例如sales_data.pyfrom pydantic import BaseModel, Field, validator from typing import List, Optional from datetime import datetime class SalesRecord(BaseModel): order_id: str Field(..., min_length10, max_length32) customer_id: int Field(..., ge100000, le999999999) amount: float Field(..., ge0.01, le9999999.99) created_at: datetime region_code: str Field(..., patternr^[A-Z]{2}-[0-9]{3}$) validator(amount) def amount_must_be_positive(cls, v): if v 0: raise ValueError(amount must be positive) return v class SalesDataContract(BaseModel): records: List[SalesRecord] batch_timestamp: datetime source_system: str Field(..., patternr^(erp|pos|crm)$)Great Expectations Suite定义动态契约在CI流水线中运行数据质量检查# expectations/sales_data.yml expectations: - expectation_type: expect_column_values_to_not_be_null kwargs: {column: order_id} - expectation_type: expect_column_values_to_match_regex kwargs: {column: region_code, regex: ^[A-Z]{2}-[0-9]{3}$} - expectation_type: expect_column_mean_to_be_between kwargs: {column: amount, min_value: 50.0, max_value: 5000.0} - expectation_type: expect_table_row_count_to_be_between kwargs: {min_value: 10000, max_value: 50000}每次数据入库前先运行great_expectations checkpoint run sales_data失败则阻断Pipeline。我们要求所有契约变更必须走Git PR流程且需附带影响分析报告——例如修改amount字段最大值必须说明对下游模型训练数据分布的影响。注意数据契约必须包含业务语义注释。比如region_code字段旁必须写明“此编码遵循ISO 3166-2标准前两位为国家码后三位为省级行政区划代码如CN-110代表北京市”。纯技术约束无法防止业务逻辑错误。3.2 特征工厂层构建可复用、可追溯、可回滚的特征生命周期特征工厂不是ETL脚本集合而是具备版本控制、依赖图谱、血缘追踪的特征操作系统。我们基于Feast 0.28定制开发了Feature Registry v2核心能力如下特征版本原子性每个特征定义FeatureView绑定Git commit hash例如user_active_days_v3abc1234。模型训练时指定特征版本确保可复现。跨源特征融合支持SQL JOIN Python UDF混合计算。例如user_lifetime_value特征需融合CRM表用户等级、POS表历史消费、ERP表退货率我们用DAG定义依赖关系# features/user_ltv.py from feast import FeatureView, Entity, Field from feast.types import Float32, Int32, String user Entity(nameuser_id, join_keys[user_id]) user_ltv_fv FeatureView( nameuser_lifetime_value, entities[user], ttltimedelta(days365), schema[ Field(nameltv_score, dtypeFloat32), Field(nameltv_rank, dtypeInt32), Field(nameltv_segment, dtypeString), ], sourceBigQuerySource( tableproject.dataset.user_ltv_features, timestamp_fieldevent_timestamp, created_timestamp_columncreated_timestamp, ), tags{owner: risk-team, domain: finance}, onlineTrue, offlineTrue, )特征血缘追踪通过feast apply自动生成DAG图点击任一特征可下钻查看上游数据源、计算SQL、依赖的其他特征、使用该特征的模型列表、最近一次更新时间。实操关键点我们禁止直接在模型代码中写SQL计算特征。所有特征必须注册到Feature Registry模型通过get_online_features()或get_historical_features()获取。这样做的代价是初期开发速度慢20%但换来的是特征复用率提升300%同一user_age_group特征被7个模型共用以及故障定位时间从小时级降至分钟级。3.3 模型编排层用Kubeflow Pipelines实现端到端可审计流水线模型编排层的核心矛盾是既要支持算法研究员快速实验又要保障生产环境稳定可靠。我们的解法是双流水线架构Research Pipeline本地/Notebook允许自由使用PyTorch Lightning、HuggingFace Trainer等框架输出标准化模型包.modelpkg格式。Production PipelineKubeflow严格限定组件接口所有步骤必须实现ComponentInterfacefrom kfp import components class TrainComponent(components.BaseComponent): def __init__(self, model_package_path: str, train_data_uri: str, val_data_uri: str, hyperparams: dict): super().__init__() self.model_package_path model_package_path self.train_data_uri train_data_uri self.val_data_uri val_data_uri self.hyperparams hyperparams def execute(self) - dict: # 必须返回标准化输出字典 return { model_uri: gs://bucket/models/v3.2.1/model.onnx, metrics: {accuracy: 0.923, f1: 0.891}, feature_importance: [...], resource_usage: {gpu_hours: 4.2, cpu_hours: 12.7} }Production Pipeline强制包含四个阶段Validation Stage校验模型包完整性签名验证、ONNX格式检查、输入输出schema匹配Staging Stage在隔离环境运行端到端推理对比baseline模型输出差异PSI 0.05Canary Stage按流量比例路由同时收集新旧模型指标自动计算lift值Promotion Stage满足lift 0.02 error_rate_delta 0.001才自动升级实操心得Kubeflow的Argo Workflow引擎默认不支持GPU资源弹性伸缩。我们在节点池配置中启用nvidia.com/gpu: 1作为最小单位并在Pipeline YAML中显式声明- name: train-step container: image: nvidia/cuda:11.7-runtime-ubuntu20.04 resources: limits: nvidia.com/gpu: 1 memory: 32Gi cpu: 8否则会出现GPU资源争抢导致训练中断。3.4 服务契约层用gRPCOpenAPI双协议保障服务可靠性服务契约层必须同时满足机器可读gRPC和人可读OpenAPI要求。我们采用Protocol Buffer First设计定义model_service.protosyntax proto3; package ai.serving; service ModelService { rpc Predict(PredictRequest) returns (PredictResponse) { option (google.api.http) { post: /v1/predict body: * }; } } message PredictRequest { string model_version 1; // 必填格式v3.2.1 bytes input_tensor 2; // 序列化后的TensorProto mapstring, string metadata 3; // 业务上下文如user_id, device_type } message PredictResponse { bytes output_tensor 1; string model_version 2; string trace_id 3; int32 latency_ms 4; bool is_degraded 5; // true表示降级至fallback模型 }自动生成gRPC ServerPython和OpenAPI文档Swagger UI# protoc生成Python stub protoc --python_out. --grpc_python_out. model_service.proto # 使用grpc-gateway生成REST gateway protoc -I/usr/local/include -I. \ -I$GOPATH/src \ -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \ --grpc-gateway_outlogtostderrtrue:. \ model_service.proto关键契约条款超时契约gRPC call timeout ≤ 100msHTTP fallback timeout ≤ 300ms降级契约当主模型P99 150ms连续5次自动切换至v2模型并在响应头中添加X-Model-Status: degraded-v2限流契约按model_versionclient_ip组合限流每秒1000 QPS超限返回429并携带Retry-After: 1我们曾因忽略metadata字段的大小限制导致移动端SDK传入超长user_behavior_history字符串引发服务端OOM。现在强制要求所有mapstring, string字段value长度≤1024字节超长自动截断并记录warn日志。3.5 观测闭环层用eBPFPrometheus构建AI服务黄金指标体系观测层不能只看CPU/Memory必须定义AI特有的黄金指标Golden Signals指标类别指标名称计算方式告警阈值数据来源准确性model_output_driftPSIPopulation Stability Index0.15特征分布对比可靠性inference_error_ratefailed_requests / total_requests0.005gRPC status code时效性p99_latency_msP99响应延迟150mseBPF内核探针公平性group_fairness_ratiomin(group_accuracy) / max(group_accuracy)0.85在线A/B测试数据采集栈eBPF探针在gRPC Server进程注入bpftrace脚本捕获每个RPC的start_ts、end_ts、status_code、model_version直送Prometheus# bpftrace -e uprobe:/path/to/server:grpc::ServerContext::Finish { start[tid] nsecs; } uretprobe:/path/to/server:grpc::ServerContext::Finish /start[tid]/ { $latency nsecs - start[tid]; p99_latency[comm] quantize($latency / 1000000); error_rate[comm, args-status.code()] count(); delete(start[tid]); }Prometheus Rule定义model_output_drift告警规则- alert: ModelOutputDriftHigh expr: max by (model_version) (rate(model_output_psi{jobmodel-serving}[1h])) 0.15 for: 15m labels: severity: warning annotations: summary: Model {{ $labels.model_version }} output drift high description: PSI{{ $value }} 0.15 for 15 minutesGrafana Dashboard构建“AI Service Health”看板包含5个核心面板黄金指标趋势、特征漂移热力图、模型版本流量占比、错误类型分布、资源利用率TOP5。关键经验eBPF探针必须做采样率控制。全量采集会导致内核负载飙升。我们采用动态采样当inference_qps 1000时自动启用1:100采样当p99_latency 200ms时临时切为1:10采样以获取更细粒度诊断数据。4. 实操全流程从零构建一个电池健康预测服务的完整记录4.1 环境准备与工具链初始化所有操作在Ubuntu 22.04 LTS服务器32C64G 2×A100 80GB上完成。工具链版本严格锁定Python 3.10.12通过pyenv管理Kubeflow Pipelines 1.8.2非最新版因1.9引入Breaking ChangeFeast 0.28.00.29的online store API不兼容Prometheus 2.45.02.46的remote_write配置变更初始化命令# 创建工程目录 mkdir -p ~/ai-engineering-from-scratch/{data,features,models,serving,observability} cd ~/ai-engineering-from-scratch # 初始化Git仓库含pre-commit hooks git init pre-commit install # 安装核心依赖requirements.txt已锁定版本 pip install -r requirements.txt # 包含feast0.28.0, kfp1.8.12, ... # 配置Kubeflow集群已预装 export KF_PIPELINES_ENDPOINThttps://kubeflow.example.com export KF_PIPELINES_NAMESPACEkubeflow-user # 初始化Feast Feature Store feast init feature_repo cd feature_repo feast apply # 创建online storeRedis和offline storeBigQuery注意Feast的feast apply会创建Cloud SQL实例费用较高。我们改用本地RedisPostgreSQL组合在feature_store.yaml中配置online_store: type: redis connection_string: redis://localhost:6379/0 offline_store: type: postgres host: localhost port: 5432 database: feast_offline user: feast password: feast1234.2 数据契约层落地定义电池时序数据Schema电池健康预测的核心数据源是BMS电池管理系统上传的时序数据每秒采集12个字段。我们定义battery_telemetry.pyfrom pydantic import BaseModel, Field, validator from typing import List, Optional from datetime import datetime class BatteryTelemetry(BaseModel): device_id: str Field(..., min_length12, max_length32) timestamp: datetime voltage_v: float Field(..., ge0.0, le1000.0) current_a: float Field(..., ge-500.0, le500.0) temperature_c: float Field(..., ge-40.0, le125.0) soc_percent: float Field(..., ge0.0, le100.0) soh_percent: float Field(..., ge0.0, le100.0) # State of Health cycle_count: int Field(..., ge0, le10000) charge_power_kw: float Field(..., ge0.0, le500.0) discharge_power_kw: float Field(..., ge0.0, le500.0) internal_resistance_mohm: float Field(..., ge0.0, le1000.0) fault_code: int Field(..., ge0, le255) validator(voltage_v, current_a, temperature_c) def sensor_range_check(cls, v, field): if field.name voltage_v and (v 0 or v 1000): raise ValueError(f{field.name} out of physical range) if field.name current_a and abs(v) 500: raise ValueError(f{field.name} exceeds max current rating) return v class TelemetryBatch(BaseModel): records: List[BatteryTelemetry] batch_id: str ingestion_time: datetime source_system: str bms-v2.3同步编写Great Expectations Suiteexpectations/battery_telemetry.yml重点检查voltage_v与current_a的协方差应为负相关充电时电压升电流降放电反之soh_percent必须单调递减除非维修重置fault_code为0时所有传感器值必须在合理范围内CI流水线中加入契约验证# .github/workflows/data-contract.yml name: Data Contract Validation on: [push] jobs: validate: runs-on: ubuntu-latest steps: - uses: actions/checkoutv3 - name: Setup Python uses: actions/setup-pythonv4 with: python-version: 3.10 - name: Install dependencies run: | pip install great-expectations0.17.10 pip install pandas1.5.3 - name: Run Great Expectations run: | cd feature_repo great_expectations checkpoint run battery_telemetry4.3 特征工厂层构建从原始时序到健康状态特征电池健康预测的关键特征不是原始传感器值而是时序统计特征和状态转移特征。我们定义features/battery_health.pyfrom feast import FeatureView, Entity, Field from feast.types import Float32, Int32, String from feast.infra.offline_stores.file_source import FileSource from datetime import timedelta battery Entity(namedevice_id, join_keys[device_id]) # 基础统计特征滑动窗口 battery_stats_fv FeatureView( namebattery_stats, entities[battery], ttltimedelta(days30), schema[ Field(namevoltage_std_1h, dtypeFloat32), Field(nametemp_max_24h, dtypeFloat32), Field(namecycle_count_delta_7d, dtypeInt32), Field(namesoh_decay_rate_30d, dtypeFloat32), # SOH下降斜率 ], sourceFileSource( pathgs://bucket/telemetry/features/stats/, timestamp_fieldevent_timestamp, ), onlineTrue, offlineTrue, ) # 状态转移特征基于SOH突变检测 battery_state_fv FeatureView( namebattery_state, entities[battery], ttltimedelta(days7), schema[ Field(namestate_transition_count_30d, dtypeInt32), # SOH突变次数 Field(namelast_transition_type, dtypeString), # capacity_loss or internal_resist_rise Field(nametransition_severity, dtypeFloat32), # 突变幅度 ], sourceFileSource( pathgs://bucket/telemetry/features/state/, timestamp_fieldevent_timestamp, ), onlineTrue, offlineTrue, )特征计算使用Spark作业jobs/compute_battery_features.pyfrom pyspark.sql import SparkSession from pyspark.sql.functions import * from pyspark.sql.window import Window spark SparkSession.builder.appName(BatteryFeatures).getOrCreate() # 读取原始时序数据 df spark.read.format(parquet).load(gs://bucket/raw/telemetry/) # 计算电压标准差1小时窗口 window_1h Window.partitionBy(device_id).orderBy(timestamp).rowsBetween(-3600, 0) df df.withColumn(voltage_std_1h, stddev(voltage_v).over(window_1h)) # 计算SOH衰减率线性回归斜率 window_30d Window.partitionBy(device_id).orderBy(timestamp).rowsBetween(-2592000, 0) df df.withColumn(soh_decay_rate_30d, slope(timestamp, soh_percent).over(window_30d)) # 检测SOH突变3σ原则 soh_stats df.groupBy(device_id).agg( mean(soh_percent).alias(soh_mean), stddev(soh_percent).alias(soh_std) ) df df.join(soh_stats, device_id) df df.withColumn(is_soh_anomaly, abs(col(soh_percent) - col(soh_mean)) 3 * col(soh_std)) # 写入特征存储 df.write.format(parquet).mode(overwrite).save(gs://bucket/telemetry/features/stats/)实操心得Spark窗口函数在大数据量下性能极差。我们将1小时窗口拆分为“固定分桶增量更新”先按5分钟分桶计算统计量再用MapReduce聚合。实测将特征计算耗时从8.2小时降至27分钟。4.4 模型编排层实现Kubeflow Pipeline端到端训练定义pipelines/battery_health_pipeline.pyfrom kfp import dsl from kfp.components import create_component_from_func dsl.component def load_data_op() - str: 加载特征数据 # 返回GCS路径 return gs://bucket/features/battery_health/ dsl.component def train_model_op( data_uri: str, model_package_path: str, hyperparams: dict ) - dict: 训练模型并返回指标 import joblib from sklearn.ensemble import RandomForestRegressor # 加载特征 X, y load_features(data_uri) # 训练 model RandomForestRegressor(**hyperparams) model.fit(X, y) # 评估 y_pred model.predict(X) mae mean_absolute_error(y, y_pred) # 保存模型 joblib.dump(model, f{model_package_path}/model.pkl) return { model_uri: f{model_package_path}/model.pkl, metrics: {mae: mae}, feature_importance: model.feature_importances_.tolist() } dsl.pipeline( nameBattery Health Prediction Pipeline, descriptionTrain battery SOH prediction model ) def battery_health_pipeline( data_uri: str gs://bucket/features/battery_health/, model_package_path: str gs://bucket/models/battery_health/v1.0.0/, n_estimators: int 100, max_depth: int 10 ): load_task load_data_op() train_task train_model_op( data_uriload_task.output, model_package_pathmodel_package_path, hyperparams{n_estimators: n_estimators, max_depth: max_depth} )提交Pipeline# 编译为YAML dsl_compiler.Compiler().compile( pipeline_funcbattery_health_pipeline, package_pathbattery_health_pipeline.yaml ) # 提交到Kubeflow kfp_client kfp.Client(hostKF_PIPELINES_ENDPOINT) experiment kfp_client.create_experiment(namebattery-health) run kfp_client.run_pipeline( experiment_idexperiment.id, job_nametrain-battery-health-v1.0.0, pipeline_package_pathbattery_health_pipeline.yaml, params{ data_uri: gs://bucket/features/battery_health/, model_package_path: gs://bucket/models/battery_health/v1.0.0/, n_estimators: 200, max_depth: 15 } )Pipeline执行后自动触发Validation Stage下载模型包验证model.pkl可反序列化运行onnxruntime推理检查输入输出shape匹配对比baseline模型v0.9.0在相同测试集上的MAE差异4.5 服务契约层部署gRPC Server与金丝雀发布模型服务使用fastapi-grpc框架非纯gRPC因需HTTP fallback# serving/main.py from fastapi import FastAPI, HTTPException from pydantic import BaseModel import joblib import numpy as np from google.protobuf.json_format import MessageToJson from concurrent.futures import ThreadPoolExecutor import asyncio app FastAPI() # 加载模型支持热更新 models {} model_lock asyncio.Lock() app.on_event(startup) async def load_initial_model(): global models models[v1.0.0] joblib.load(gs://bucket/models/battery_health/v1.0.0/model.pkl) app.post(/v1/predict) async def predict(request: PredictRequest): # 校验契约 if not request.model_version: raise HTTPException(400, model_version required) if request.model_version not in models: # 自动加载新版本 try: models[request.model_version] joblib.load( fgs://bucket/models/battery_health/{request.model_version}/model.pkl ) except Exception as e: raise HTTPException(404, fmodel {request.model_version} not found) # 执行推理 start_time time.time() try: X np.frombuffer(request.input_tensor, dtypenp.float32).reshape(1, -1) y_pred models[request.model_version].predict(X)[0] latency_ms int((time.time() - start_time) * 1000) if latency_ms 150: # 触发降级 y_pred models[v0.9.0].predict(X)[0] is_degraded True else: is_degraded False return PredictResponse( output_tensory_pred.tobytes(), model_versionrequest.model_version, trace_idrequest.metadata.get(trace_id, unknown), latency_mslatency_ms, is_degradedis_degraded ) except Exception as e: raise HTTPException(500, finference failed: {str(e)})金丝雀发布通过Istio VirtualService实现# istio/virtual-service.yaml apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: battery-model spec: hosts: - battery-api.example.com http: - route: - destination: host: battery-model subset: v1.0.0 weight: 5 - destination: host: battery-model subset: v0.9.0 weight: 95 --- apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: battery-model spec: host: battery-model subsets: - name: v1.0.0 labels: version: v1.0.0 - name: v0.9.0 labels: version: v0.9.04.6 观测闭环层集成eBPF探针与Prometheus告警在服务Pod中注入eBPF探针observability/ebpf_probe.bpf.c#include vmlinux.h #include bpf/bpf_tracing.h #include bpf/bpf_helpers.h struct { __uint(type, BPF_MAP_TYPE_HASH); __type(key, u64); // pid_tgid __type(value, u64); // start_ns __uint(max_entries, 10240); } start SEC(.maps); SEC(uprobe/entry) int entry(struct pt_regs *ctx) { u64 pid_tgid bpf_get_current_pid_tgid(); u64 ts bpf_ktime_get_ns(); bpf_map_update_elem(start, pid_tgid, ts, BPF_ANY); return 0; } SEC(uretprobe/exit) int exit(struct pt_regs *ctx) { u64 pid_tgid
阅读完成 · 觉得有帮助?
咨询建站