flink学习与如何在springboot项目中使用flink

flink:Apache Flink 一种流式计算框架,高吞吐低延迟的数据处理方案

原理:把所有数据视为流,由事件驱动,每次事件到达触发计算

与传统批处理的区别:Hadoop/Spark batch 固定数据集处理任务,任务所有逻辑执行完成一次提交

复制代码
  Hadoop优点:分布式文件存储,可动态组装数据库集群,实现高可靠、可容错、可扩展

  可以把多台普通服务器集合成大数据集群,数据在每个节点上分别计算,最后汇总成完整数据

   组成:

   HDFS分布式文件系统-将数据拆分分别存在集群的不同节点上、通过副本机制保证数据安全

   上传 300MB 文件 → 分成 3 个 block → 分布到 3 台机器上,每个 block 3 副本

   包含两个关键角色:NameNode-元数据管理节点-记录数据所在的节点位置

                                     DataNode-存储数据的节点

   MapReduce分布式计算模型-在不同节点上进行不同数据的计算,最后归约汇总输出完整结果

   两个阶段:Map-映射-分布式处理数据分片

                     Reduce-归约-汇总map输出

   Yarn资源调度管理-集群资源调度管理、节点资源调度管理、单个应用的生命周期管理

   使用场景:非实时性的离线数据任务(比如一些T+1更新的分析数据、离线日志分析)

主要使用场景:高实时性业务(监控告警、风控、推荐、广告投放、实时数仓)

在项目中集成flink-示例:动态统计5min内的点击数(强实时性统计,差一秒可能数据变更都非常大)

首先在pom中添加依赖 - 举例在kafka信息流中计算

java 复制代码
<dependencies>
    <!-- Flink 核心依赖 -->
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-streaming-java</artifactId>
        <version>1.18.1</version>
    </dependency>

    <!-- 如果需要 Kafka Source/Sink -->
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-connector-kafka</artifactId>
        <version>1.18.1</version>
    </dependency>

    <!-- Spring Boot 基础依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
</dependencies>在这里插入代码片

注意:Flink 版本建议与生产集群一致,避免依赖冲突。

然后新建一个 Flink 任务类,例如 FlinkStreamJob.java:

java 复制代码
import org.apache.flink.api.common.eventtime.WatermarkStrategy;
import org.apache.flink.api.common.serialization.SimpleStringSchema;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.connector.kafka.source.KafkaSource;
import org.apache.flink.connector.kafka.sink.KafkaSink;

import org.springframework.stereotype.Component;

@Component
public class FlinkStreamJob {

    public void start() throws Exception {
        // 1. 创建执行环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        // 2. 配置 Kafka Source - 从kafka读取数据流
        KafkaSource<String> source = KafkaSource.<String>builder()
                .setBootstrapServers("localhost:9092")
                .setTopics("input-topic")
                .setGroupId("flink-group")
                .setValueOnlyDeserializer(new SimpleStringSchema())
                .build();

        DataStream<String> stream = env
                .fromSource(source, WatermarkStrategy.noWatermarks(), "Kafka Source");

        // 3. 数据转换逻辑
        DataStream<String> result = stream
                .map(value -> "Processed: " + value);

        // 4. 输出到 Kafka Sink 将结果流输出到kafka去
        KafkaSink<String> sink = KafkaSink.<String>builder()
                .setBootstrapServers("localhost:9092")
                .setRecordSerializer(KafkaRecordSerializationSchema.builder()
                        .setTopic("output-topic")
                        .setValueSerializationSchema(new SimpleStringSchema())
                        .build())
                .build();

        result.sinkTo(sink);

        // 5. 启动作业
        env.execute("SpringBoot-Flink-Job");
    }
}

在springboot中集成这个任务

例如在 Application.java配置,启动SpringBoot应用时,Flink作业会自动运行

java 复制代码
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.beans.factory.annotation.Autowired;

@SpringBootApplication
public class Application implements CommandLineRunner {

    @Autowired
    private FlinkStreamJob flinkJob;

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        flinkJob.start();
    }
}

控制台输出类似:

Starting job SpringBoot-Flink-Job (JobID=xxxxxx)

Connected to Kafka source: input-topic

Producing to Kafka sink: output-topic

此时SpringBoot应用实际上已经成为一个可独立运行的 Flink 流任务服务

**

如果我创建了一个stream流式任务job,中间服务重启了,job会中断吗?

**

结论:如果是在springboot内集成的flink流,会中断,job会中断,内存状态丢失,重启后会重新从头计算

原因:此时flink是由springboot的jvm管理的,服务重启jvm会清空,对应的信息和状态就不存在了,就会中断计算逻辑,等待重启后重新开始

方案 1:启用 Checkpoint + Savepoint(推荐)

在代码中启用 Checkpoint,可以让 Flink 自动保存状态。

当任务重启时,会从最近的 Checkpoint 恢复,不中断计算结果的连续性。

示例:

java 复制代码
env.enableCheckpointing(60000); // 每 60 秒做一次 checkpoint

env.getCheckpointConfig().setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE);
env.getCheckpointConfig().setMinPauseBetweenCheckpoints(30000);
env.getCheckpointConfig().setCheckpointTimeout(10000);
env.getCheckpointConfig().setMaxConcurrentCheckpoints(1);

// 可选:设置状态后端(例如 RocksDB 或 FileSystem)
env.setStateBackend(new HashMapStateBackend());
env.getCheckpointConfig().setCheckpointStorage("file:///tmp/flink-checkpoints");

效果:

即使服务重启,任务会在下次启动时自动从上次的 checkpoint 恢复

不会重复消费 Kafka

数据唯一不会重复处理

方案 2:把 Flink Job 运行在 独立集群中

即把 Flink Job 从 Spring Boot 进程中"独立"出来,

用 Spring Boot 作为 提交 / 监控 / 管理端。

运行方式:

flink run -c com.example.flinkdemo.job.FlinkKafkaJob

target/springboot-flink-demo-1.0.0.jar

优点:

Job 运行在 Flink 集群中;

不受 Spring Boot 重启影响;

可以自动从 checkpoint 恢复;

高可用 (HA) 可配置多个 JobManager。

Spring Boot 这时只做:

任务发布;

状态监控;

参数配置

相关推荐
程序定小飞17 小时前
基于springboot的体育馆使用预约平台的设计与实现
java·开发语言·spring boot·后端·spring
计算机毕业设计小途17 小时前
计算机毕业设计推荐:基于SpringBoot的水产养殖管理系统【Java+spring boot+MySQL、Java项目、Java毕设、Java项目定制定做】
java·spring boot·mysql
s***45317 小时前
解决Spring Boot中Druid连接池“discard long time none received connection“警告
spring boot·后端·oracle
执笔论英雄17 小时前
【大模型训练】deepseek MTPpp阶段的输入数据哪里来
学习
Dreamboat-L17 小时前
IDEA中在springboot项目中整合Mybatis时@Autowired时,提示Could not autowire解决方案
spring boot·intellij-idea·mybatis
chenzhou__17 小时前
LinuxC语言并发程序笔记(第二十天)
linux·c语言·笔记·学习
立志成为大牛的小牛17 小时前
数据结构——四十九、B树的删除与插入
数据结构·学习·程序人生·考研·算法
v***85719 小时前
Spring Boot 集成 MyBatis 全面讲解
spring boot·后端·mybatis
武昌库里写JAVA19 小时前
Java如何快速入门?Java基础_Java入门
java·vue.js·spring boot·后端·sql
h***346319 小时前
SpringBoot(整合MyBatis + MyBatis-Plus + MyBatisX插件使用)
spring boot·tomcat·mybatis