Flink 自定义 Failure Enricher:把失败“打标签”,让告警、归因、统计更聪明

1、它解决什么问题?

FailureEnricher 的典型用途:

  • 故障分类/归因 :给失败贴上 type=Systemtype=Usercomponent=Kafkareason=AuthFailed 等标签
  • 告警路由:不同标签推送到不同 oncall(平台组/业务组/中间件组)
  • 可观测性增强:把标签送到外部系统(Prometheus/OTel/自研平台)做统计报表
  • 联动通知 :在 processFailure() 里调用外部通知系统(注意:建议异步且要兜底超时)

触发时机:

  • 每次 JobManager 在运行时收到异常报告时都会触发 FailureEnrichers
  • Enricher 可以 异步 返回 labels(CompletableFuture<Map<String,String>>

2、插件结构与加载方式(重点)

2.1 你要实现的 3 件事

  1. 实现 FailureEnricher
  2. 实现 FailureEnricherFactory
  3. 使用 Java SPI 注册工厂:
    META-INF/services/org.apache.flink.core.failure.FailureEnricherFactory

然后把 jar 放到 Flink plugins/ 下的某个目录,例如:

text 复制代码
$FLINK_HOME/plugins/
  failure-enrichment/
    my-failure-enricher.jar

2.2 关键约束:output keys 必须唯一

每个 FailureEnricher 都要声明自己可能输出的 key 集合(getOutputKeys())。
所有 enrichers 的 key 集合必须互不重叠 ,否则有重叠 key 的 enrichers 会被忽略 (直接不生效)。

实践建议:统一加前缀,例如 fe.org.

  • fe.type
  • fe.component
  • fe.owner
  • fe.ticket

3、最小可用示例(可直接改成你们的规则)

3.1 Factory

java 复制代码
public class CustomFailureEnricherFactory implements FailureEnricherFactory {
   @Override
   public FailureEnricher createFailureEnricher(Configuration conf) {
        return new CustomEnricher(conf);
   }
}

3.2 Enricher(示例:按异常类型简单分类)

java 复制代码
public class CustomEnricher implements FailureEnricher {
    private final Set<String> outputKeys;

    public CustomEnricher(Configuration conf) {
        this.outputKeys = Set.of("fe.type", "fe.component");
    }

    @Override
    public Set<String> getOutputKeys() {
        return outputKeys;
    }

    @Override
    public CompletableFuture<Map<String, String>> processFailure(Throwable cause, Context context) {
        return CompletableFuture.supplyAsync(() -> {
            Map<String, String> labels = new HashMap<>();

            String msg = String.valueOf(cause.getMessage());
            labels.put("fe.type", "System");

            if (msg.contains("org.apache.kafka") || msg.contains("Sasl") || msg.contains("Kafka")) {
                labels.put("fe.component", "Kafka");
            } else if (msg.contains("org.apache.hadoop") || msg.contains("hdfs")) {
                labels.put("fe.component", "HDFS");
            } else {
                labels.put("fe.component", "Unknown");
            }

            return labels;
        });
    }
}

生产建议:这里的异步线程池别用默认 ForkJoinPool,最好用你自己可控的 executor,并设置超时/熔断,避免 enrichment 本身成为压力源。

3.3 SPI 文件内容

文件路径:

text 复制代码
META-INF/services/org.apache.flink.core.failure.FailureEnricherFactory

文件内容(一行一个工厂类名):

text 复制代码
com.yourcompany.flink.failure.CustomFailureEnricherFactory

4、配置:不配就不会启动

JobManager 启动时加载 FailureEnricher 插件,但 是否启用由配置决定:

properties 复制代码
jobmanager.failure-enrichers = com.yourcompany.flink.failure.CustomEnricher

注意点:

  • 如果 jobmanager.failure-enrichers 为空:不会启动任何 enricher
  • 配置的是 FailureEnricher 的类名(按你给的示例是这样写的),确保与实际类一致

5、如何验证它是否生效?

5.1 看 JobManager 日志

启动时会出现类似日志:

text 复制代码
Found failure enricher com.xxx.CustomEnricher at jar:file:/path/to/flink/plugins/failure-enrichment/xxx.jar!/...

5.2 看 REST API 输出的 failureLabels

从 JobManager REST API 查询时,会出现:

json 复制代码
"failureLabels": {
  "fe.type": "System",
  "fe.component": "Kafka"
}

你们可以用这个字段做:

  • 告警系统的规则匹配
  • 失败原因的聚合统计(按 label 分组)
  • 自助排障页的"失败类型"展示

6、生产落地建议(少踩坑)

  • label key 规范化:统一前缀 + 固定枚举值,避免团队各写各的导致不可聚合
  • 异步要可控:线程池、超时、异常兜底(enricher 失败不应影响主流程)
  • 避免重 IO/外部依赖:如要调用外部系统,务必做熔断/缓存/降级(否则故障时雪上加霜)
  • 和 Metrics/Event/Trace 打通 :failureLabels 很适合与 structured logging 的 flink-job-id 一起作为关联维度
相关推荐
培培说证3 小时前
2026 高职计算机专业证书报考条件是什么?
大数据
BlockWay3 小时前
西甲赛程搬进平台:WEEX以竞猜开启区域合作落地
大数据·人工智能·算法·安全
SailingCoder4 小时前
【 从“打补丁“到“换思路“ 】一次企业级 AI Agent 的架构拐点
大数据·前端·人工智能·面试·架构·agent
微风中的麦穗5 小时前
【SQL Server 2019】企业级数据库系统—数据库SQL Server 2019保姆级详细图文下载安装完全指南
大数据·数据库·sqlserver·云计算·个人开发·运维必备·sqlserver2019
qyresearch_5 小时前
圆形连接器外壳:全球市场格局、技术趋势与行业展望
大数据
海兰6 小时前
ES 9.3.0 模型上下文优化
大数据·elasticsearch·搜索引擎
躺柒6 小时前
读人工智能全球格局:未来趋势与中国位势06人类的未来(下)
大数据·人工智能·算法·ai·智能
码云数智-大飞7 小时前
小程序制作平台有哪些?SaaS小程序制作平台对比评测
大数据·人工智能
ctrigger8 小时前
家和万事兴
大数据·人工智能·生活