4. Flink CEP 环境搭建:集群部署模式、开发环境依赖配置与第一个CEP程序

本章是Flink CEP风控巡检课程的实践起点。我们将从Flink集群的三种部署模式入手,完成开发环境的Maven/Gradle依赖配置,并编写第一个CEP Hello World程序,验证整个链路是否通畅。掌握本章内容后,你将具备独立搭建Flink CEP开发与运行环境的能力。

4.1 Flink集群部署模式对比

Flink支持多种部署模式,以适应不同规模和运维要求的风控场景。下表列出了三种主流模式的适用场景与核心差异:

部署模式 资源管理 适用场景 启动复杂度 典型风控场景
Standalone Flink自身管理 开发测试、小规模验证 低 本地CEP规则调试
YARN Hadoop YARN 生产环境、已有Hadoop集群 中 离线/准实时风控批流一体
Kubernetes K8s 容器化、弹性伸缩、云原生 较高 高并发实时交易监控
推荐建议: 本教程后续所有CEP示例均基于Standalone模式运行,便于快速迭代。生产环境建议优先使用Kubernetes模式,以获得更好的资源隔离与自动扩缩容能力。

4.2 开发环境依赖配置

无论使用Maven还是Gradle,核心依赖项一致。以下分别给出两种构建工具的配置示例,请根据项目实际情况选择。

4.2.1 Maven依赖配置(pom.xml)

<properties>
    <flink.version>1.17.1</flink.version>
    <scala.binary.version>2.12</scala.binary.version>
</properties>

<dependencies>
    <!-- Flink核心 -->
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-java</artifactId>
        <version>${flink.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-streaming-java</artifactId>
        <version>${flink.version}</version>
    </dependency>
    <!-- Flink CEP -->
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-cep</artifactId>
        <version>${flink.version}</version>
    </dependency>
    <!-- 客户端提交 -->
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-clients</artifactId>
        <version>${flink.version}</version>
    </dependency>
</dependencies>

4.2.2 Gradle依赖配置(build.gradle)

plugins {
    id 'java'
}

group 'com.risk.cep'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.apache.flink:flink-java:1.17.1'
    implementation 'org.apache.flink:flink-streaming-java:1.17.1'
    implementation 'org.apache.flink:flink-cep:1.17.1'
    implementation 'org.apache.flink:flink-clients:1.17.1'
}
版本一致性: flink-cep、flink-streaming-java、flink-clients 三个模块的版本号必须完全一致,否则运行时会出现类加载冲突或NoSuchMethodError。建议统一使用 ${flink.version} 属性管理。

4.3 第一个CEP程序:Hello World

我们编写一个最简单的CEP程序:从数据流中检测连续出现两次相同数字的“重复模式”。该程序将帮助你验证环境配置是否正确,并理解CEP的基本执行流程。

4.3.1 程序核心逻辑

  • 数据源: 模拟生成整数序列 1, 2, 2, 3, 4, 5, 5, 6
  • 模式定义: 检测“连续两个相同数字”
  • 输出: 打印匹配到的重复数字对

4.3.2 完整代码

import org.apache.flink.cep.CEP;
import org.apache.flink.cep.PatternSelectFunction;
import org.apache.flink.cep.pattern.Pattern;
import org.apache.flink.cep.pattern.conditions.SimpleCondition;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;

import java.util.List;
import java.util.Map;

public class CepHelloWorld {

    public static void main(String[] args) throws Exception {
        // 1. 创建执行环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        // 2. 模拟数据源:1, 2, 2, 3, 4, 5, 5, 6
        DataStream<Integer> input = env.fromElements(1, 2, 2, 3, 4, 5, 5, 6);

        // 3. 定义CEP模式:连续两个相同数字
        Pattern<Integer, Integer> pattern = Pattern
                .<Integer>begin("first")
                .where(new SimpleCondition<Integer>() {
                    @Override
                    public boolean filter(Integer value) {
                        return true; // 接收所有数字
                    }
                })
                .next("second")
                .where(new SimpleCondition<Integer>() {
                    @Override
                    public boolean filter(Integer value, Context<Integer> ctx) throws Exception {
                        Integer first = ctx.getEventsForPattern("first").iterator().next();
                        return value.equals(first); // 第二个数字与第一个相同
                    }
                });

        // 4. 将模式应用到数据流
        DataStream<String> result = CEP.pattern(input, pattern)
                .select(new PatternSelectFunction<Integer, String>() {
                    @Override
                    public String select(Map<String, List<Integer>> pattern) {
                        Integer first = pattern.get("first").get(0);
                        Integer second = pattern.get("second").get(0);
                        return "检测到重复数字对: (" + first + ", " + second + ")";
                    }
                });

        // 5. 打印结果
        result.print();

        // 6. 执行任务
        env.execute("CEP Hello World");
    }
}

4.3.3 预期输出

检测到重复数字对: (2, 2)
检测到重复数字对: (5, 5)
验证要点: 如果控制台正确打印出上述两行结果,说明Flink CEP环境搭建成功,模式匹配逻辑正确。若出现ClassNotFoundException或NoClassDefFoundError,请检查依赖版本是否一致。

4.4 CEP程序执行流程

下图展示了第一个CEP Hello World程序从数据输入到结果输出的完整执行链路:

CEP Hello World 执行流程 CEP Hello World 执行流程 数据源 1,2,2,3,4,5,5,6 定义模式 连续相同数字 应用模式 CEP.pattern() 选择结果 .select() 输出结果 (2,2) (5,5) 说明: 数据流经过模式匹配引擎,只有满足“连续两个相同数字”的事件对才会被选中并输出。 本例中数字2和5各出现连续重复,因此输出两对结果。

4.5 环境验证清单

完成上述步骤后,请对照以下清单逐项确认环境就绪:

检查项 验证方法 预期结果
Flink集群状态 访问 http://localhost:8081 Web UI正常显示,TaskManager在线
依赖完整性 执行 mvn dependency:tree flink-cep、flink-streaming-java等依赖无冲突
CEP程序运行 运行CepHelloWorld主类 控制台输出两行重复数字对
日志无异常 检查控制台日志 无ClassNotFoundException或NoClassDefFoundError
快速排错: 如果程序运行后无任何输出,请检查是否忘记调用 env.execute();如果输出乱序,可设置 env.setParallelism(1) 确保事件顺序与输入一致。