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 这时只做:

任务发布;

状态监控;

参数配置

相关推荐
JIngJaneIL10 小时前
停车场管理|停车预约管理|基于Springboot的停车场管理系统设计与实现(源码+数据库+文档)
java·数据库·spring boot·后端·论文·毕设·停车场管理系统
我想我不够好。11 小时前
plc学习路线
学习·plc
苹果醋313 小时前
element-ui源码阅读-样式
java·运维·spring boot·mysql·nginx
Rock_yzh13 小时前
AI学习日记——Transformer的架构:编码器与解码器
人工智能·深度学习·神经网络·学习·transformer
没有bug.的程序员13 小时前
@Controller、@RestController、@RequestMapping 解析机制
java·spring boot·spring·controller·requestmapping·restcontroller
乔冠宇14 小时前
vue需要学习的点
前端·vue.js·学习
老华带你飞15 小时前
商城推荐系统|基于SprinBoot+vue的商城推荐系统(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·毕设·商城推荐系统
一 乐15 小时前
物业管理系统|小区物业管理|基于SprinBoot+vue的小区物业管理系统(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·后端
yolo_Yang15 小时前
【Spring Boot】Spring Boot解决循环依赖
java·spring boot·后端