- 云原生
- 容器编排
- 工作流自动化
- 任务调度
- 后端
【免费下载链接】argo-workflows
Workflow Engine for Kubernetes
Argo Workflows 在metrics.prometheus中提供三种 Prometheus 指标类型:Gauge、Counter与Histogram,其中 Histogram 用于对工作流运行中产生的数值(如任务耗时、输出参数值)做客户端聚合统计,适合回答"有多少次请求耗时小于 1 秒"这类分布类问题。本文以 Java SDK 生成的模型文档IoArgoprojWorkflowV1alpha1Histogram为核心,结合仓库内的 CRD 类型定义、控制器指标实现与真实示例,完整讲解 Histogram 的字段语义、YAML 配置方法、底层处理链路与 PromQL 查询方式。
一、Histogram 指标在 Argo Workflows 中的定位
官方文档 docs/metrics.md 明确引用了 OpenTelemetry 对三类指标工具的定义:
counter:随时间累积的值,类似汽车里程表,只会单调递增;gauge:读取时刻的当前值,类似汽车油量表;histogram:客户端侧聚合的值,如请求延迟。当关心数值统计分布时("有多少请求耗时少于 1 秒?")应选用 histogram。
Argo Workflows 把这三种类型统一建模在Prometheus结构体中,通过gauge、histogram、counter三个互斥字段之一来声明具体类型。类型常量定义于 pkg/apis/workflow/v1alpha1/workflow_types.go#L4058-L4065:
type MetricType string const ( MetricTypeGauge MetricType = "Gauge" MetricTypeHistogram MetricType = "Histogram" MetricTypeCounter MetricType = "Counter" MetricTypeUnknown MetricType = "Unknown" )Prometheus.GetMetricType()(workflow_types.go#L4103-L4114)会按Gauge → Histogram → Counter的优先级推断类型:只要p.Histogram != nil即为 Histogram。因此 Histogram 是每个工作流/模板metrics.prometheus列表中的一个独立条目类型,只能与 Gauge、Counter 互斥出现。
二、模型定义与字段语义
Java SDK 生成的模型文档 sdks/java/client/docs/IoArgoprojWorkflowV1alpha1Histogram.md 中,IoArgoprojWorkflowV1alpha1Histogram仅有如下两个属性:
| 字段 | Java 类型 | 说明 |
|---|---|---|
| buckets | List<BigDecimal> | Buckets is a list of bucket divisors for the histogram(直方图的桶除数列表) |
| value | String | Value is the value of the metric(指标的值) |
这两个字段与 CRD 底层的 Go 类型一一对应。Go 侧的Histogram结构体定义在 pkg/apis/workflow/v1alpha1/workflow_types.go#L4206-L4213:
// Histogram is a Histogram prometheus metric type Histogram struct { // Value is the value of the metric // +kubebuilder:validation:MinLength=1 Value string `json:"value" protobuf:"bytes,3,opt,name=value"` // Buckets is a list of bucket divisors for the histogram Buckets []Amount `json:"buckets" protobuf:"bytes,4,rep,name=buckets"` } func (in *Histogram) GetBuckets() []float64 { buckets := make([]float64, len(in.Buckets)) for i, bucket := range in.Buckets { buckets[i], _ = bucket.Float64() } return buckets }值得注意的细节:
value是String而非数值:因为 Argo Workflows 的指标值普遍支持模板变量(如{{workflow.duration}}、{{outputs.parameters.xxx}}),必须在运行时解析成字符串后再转为数值。CRD 上标注了MinLength=1,即该字段不允许为空字符串。buckets的类型是[]Amount:Amount是仓库自定义的数值类型(pkg/apis/workflow/v1alpha1/amount.go),内部持有json.Number并通过Float64()转成float64,GetBuckets()正是逐桶调用该方法完成转换。在 Java SDK 中对应为List<BigDecimal>,均为高精度十进制表示,避免浮点精度损失。
Histogram挂在Prometheus结构体的可选字段上(workflow_types.go#L4076-L4093),Prometheus还包含name(^[a-zA-Z_][a-zA-Z0-9_]*$)、labels、help(MinLength=1)、when等公共字段。
三、在 Workflow 中声明 Histogram 指标
仓库自带的示例 examples/custom-metrics.yaml 展示了一个完整的 Histogram 配置:它在模板random-int的metrics.prometheus下声明了random_int_step_histogram:
- name: random-int metrics: prometheus: - name: random_int_step_histogram help: "Value of the int emitted by random-int at step level" when: "{{status}} == Succeeded" # Only emit metric when step succeeds histogram: buckets: - 2.01 - 4.01 - 6.01 - 8.01 - 10.01 value: "{{outputs.parameters.rand-int-value}}"配置要点拆解:
buckets:一组递增的桶边界(bucket divisors)。控制器会为每个桶分别记录落入该边界以内的观测次数,最终在 Prometheus 端生成_bucket{le="..."}系列序列。示例中从 2.01 到 10.01 共 5 个边界,意味着输出值被切分为 6 个区间(含+Inf上界)。value:每次要观测的数值,支持模板变量。示例取上游步骤输出的参数{{outputs.parameters.rand-int-value}};在工作流级指标中常用{{workflow.duration}},在模板级则用{{duration}}。when:条件表达式,仅当条件成立(此处为步骤成功)时才上报该指标。help:必填的指标说明字符串(MinLength=1)。labels:可选键值对标签,键需符合^[a-zA-Z_][a-zA-Z0-9_]*$(MetricLabel 定义)。
运行该 Workflow 后,Prometheus 端会出现random_int_step_histogram_bucket、random_int_step_histogram_count、random_int_step_histogram_sum等序列,可用于后续分位数计算。
四、控制器侧的处理链路
1. 指标声明校验
在指标注册之前,控制器会先做合法性校验。workflow/metrics/util.go#L37-L38 中强制要求 Histogram 必须填写value:
if metric.Histogram != nil && metric.Histogram.Value == "" { return errors.New("missing histogram.value") }这与 CRD 上MinLength=1的校验约束相互印证:缺少value的 Histogram 配置会被拒绝。
2. 指标的创建与注册
workflow/metrics/metrics_custom.go#L290-L293 中,Histogram 类型会创建 OpenTelemetry 的Float64Histogram仪器,并把 YAML 中的 buckets 通过GetBuckets()转换为默认桶配置:
case metricType == wfv1.MetricTypeHistogram: return m.CreateInstrument(telemetry.Float64Histogram, metricSpec.Name, metricSpec.Help, "{item}", telemetry.WithDefaultBuckets(metricSpec.Histogram.GetBuckets()))由此可见,buckets并非仅仅透传给 Prometheus 的静态描述,而是直接决定了 OTel 仪器实例的桶划分策略,进而影响最终导出的_bucket序列粒度。
3. 数值的观测与上报
当工作流/模板满足上报条件时,metrics_custom.go#L244-L250 会把模板变量解析后的value字符串转成float64并调用Record记录一次观测:
case metricType == wfv1.MetricTypeHistogram: val, err := strconv.ParseFloat(metricSpec.Histogram.Value, 64) if err != nil { return err } // Record does its own locking if needed by the exporter baseMetric.Record(ctx, val, metricValue.getLabels())与 Gauge 的加减操作(Set/Add/Sub)不同,Histogram 没有操作符语义:每次上报就是向对应桶累积一次观测值,这也是直方图"客户端聚合分布"特性的体现。
五、用 PromQL 查询 Histogram 分布
Histogram 指标最常见的消费方式是配合histogram_quantile计算分位数。仓库自带的 Grafana 仪表盘 examples/grafana-dashboard.json 中就有现成的示例表达式(针对控制器内置的operation_duration_seconds直方图):
histogram_quantile(0.95, sum(rate(argo_workflows_operation_duration_seconds_bucket{kubernetes_namespace=~"^$ns$"}[5m])) by (le))同理,对于自定义的random_int_step_histogram,可写为:
histogram_quantile(0.95, sum(rate(random_int_step_histogram_bucket[5m])) by (le))需要提醒的是,docs/metrics.md 明确指出 Prometheus 指标不应被视为数据存储:它们只反映系统当前状态,不保证持久化,也不适合记录单个工作流实例或单次步骤的历史耗时。如需留存历史数据,应使用工作流归档或日志上报。
六、使用建议与注意事项
- 桶边界应合理覆盖业务取值范围:桶过密会拉高基数与存储开销,过疏则分位数精度下降。示例中选择 2.01、4.01 等带小数点的边界,是为了让边界与整型输出值错开,避免"值恰好等于边界"时的归属歧义。
value必须能在运行时解析为合法浮点数:若模板变量缺失或内容非法,strconv.ParseFloat会直接返回错误,导致该次上报失败。- 注意高基数风险:
labels中若使用高基数的取值(如随机值或完整工作流名),会使序列数量膨胀,官方文档对部分内置指标已用 ⚠️ 标注此类风险。 - Java SDK 使用:
IoArgoprojWorkflowV1alpha1Histogram仅用于在 Java 程序中以类型安全方式构造 Workflow CRD 对象(buckets用List<BigDecimal>、value用String),其语义与 YAML 完全一致,最终序列化结果与示例 YAML 等价。
七、相关参考
- 模型文档:sdks/java/client/docs/IoArgoprojWorkflowV1alpha1Histogram.md
- Go 类型定义:pkg/apis/workflow/v1alpha1/workflow_types.go#L4206-L4221
- 数值类型
Amount:pkg/apis/workflow/v1alpha1/amount.go - 完整指标示例:examples/custom-metrics.yaml
- 指标概念与内置指标清单:docs/metrics.md
- 控制器实现:workflow/metrics/metrics_custom.go、workflow/metrics/util.go
- Grafana 查询示例:examples/grafana-dashboard.json
- 云原生
- 容器编排
- 工作流自动化
- 任务调度
- 后端
【免费下载链接】argo-workflows
Workflow Engine for Kubernetes
相关推荐
Argo Workflows Java SDK:GithubComArgoprojArgoEventsPkgApisEventsV1alpha1GitCreds 模型详解
Argo Workflows Java SDK:GithubComArgoprojArgoEventsPkgApisEventsV1alpha1GitCreds
云原生容器编排工作流自动化任务调度后端Argo Workflows Java SDK:GithubComArgoprojArgoEventsPkgApisEventsV1alpha1PulsarTrigger 模型详解
Argo Workflows Java SDK:GithubComArgoprojArgoEventsPkgApisEventsV1alpha1PulsarTr
云原生容器编排工作流自动化任务调度后端Argo Workflows Java SDK 指南:Sensor 模型与 SensorService API 详解
Argo Workflows Java SDK 指南:Sensor 模型与 SensorService API 详解 Argo Workflows 的 Java
云原生容器编排工作流自动化任务调度后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考