springboot集成flink并发布flink集群端运行

本文介绍了如何在SpringBoot项目中集成Flink,并实现Flink作业在集群上运行。主要内容包括从Kafka读取数据,通过KeyedProcessFunction进行计算,结果写入MySQL。详细讲解了配置、打包和执行过程中的关键点,如环境搭建、日志处理、错误排查等。
摘要由CSDN通过智能技术生成

背景:近期项目需要,引入flink,研究了下flink,步步踩坑终于可以单独运行,也可发布到集群运行,记录下踩坑点。开发环境:idea+springboot(2.3.5.RELEASSE)+kafka(2.8.1)+mysql(8.0.26)。废话不多说,直接上可执行代码。

以下代码实现了某个时间间隔,设备不上传数据,判断为离线的逻辑

一、项目application创建

/**
 * flink任务提交application
 *
 * @author wangfenglei
 */
@SpringBootApplication(scanBasePackages = {"com.wfl.firefighting.flink","com.wfl.firefighting.util"})
public class DataAnalysisFlinkApplication {
    public static void main(String[] args) {
        SpringApplication.run(DataAnalysisFlinkApplication.class, args);
    }
}

二、设备状态计算主体,从kafka接收数据,然后通过KeyedProcessFunction函数进行计算,然后把离线设备输出到mysql sink,更新设备状态

/**
 * 从kafka读取数据,计算设备状态为离线后写入mysql
 *
 * @author wangfenglei
 */
@Component
@ConditionalOnProperty(name = "customer.flink.cal-device-status", havingValue = "true", matchIfMissing = false)
public class DeviceDataKafkaSource {
    private static final Logger log = LoggerFactory.getLogger(CalDeviceOfflineFunction.class);
    @Value("${spring.kafka.bootstrap-servers:localhost:9092}")
    private String kafkaServer;
    @Value("${spring.kafka.properties.sasl.jaas.config}")
    private String loginConfig;
    @Value("${customer.flink.cal-device-status-topic}")
    private String topic;
    @Autowired
    private ApplicationContext applicationContext;

    /**
     * 执行方法
     *
     * @throws Exception 异常
     */
    @PostConstruct
    public void execute() throws Exception {
        final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.enableCheckpointing(5000);
        env.setParallelism(1);
        Properties properties = new Properties();
        //kafka的节点的IP或者hostName,多个使用逗号分隔
        properties.setProperty("bootstrap.servers", kafkaServer);
        //kafka的消费者的group.id
        properties.setProperty("group.id", "data-nanlysis-flink-devicestatus");
        //设置kafka安全认证机制为PLAIN
        properties.setProperty("sasl.mechanism", "PLAIN");
        //设置kafka安全认证协议为SASL_PLAINTEXT
        properties.setProperty("security.protocol", "SASL_PLAINTEXT");
        //设置kafka登录验证用户名和密码
        properties.setProperty("sasl.jaas.config", loginConfig);

        FlinkKafkaConsumer<String> myConsumer = new FlinkKafkaConsumer<>(topic, new SimpleStringSchema(), properties);

        DataStream<String> stream = env.addSource(myConsumer);
        stream.print().setParallelism(1);

        DataStream<String> deviceStatus = stream
                //进行转换只获取设备序列码
                .map(data -> CommonConstant.GSON.fromJson(data, MsgData.class).getDevSn())
                //按照设备序列码分组
                .keyBy(new KeySelector<String, String>() {
                    @Override
                    public String getKey(String value) throws Exception {
                        return value;
                    }
                })
                //进行计算,判断周期内是否有新数据上传,没有则输出认为设备离线
                .process((CalDeviceOfflineFunction) applicationContext.getBean("calDeviceOfflineFunction"));

        //写入数据库
        deviceStatus.addSink((SinkFunction) applicationContext.getBean("deviceStatusSink"));

        //启动任务
        new Thread(() -> {
            try {
                env.execute("deviceStatusFlinkJob");
            } catch (Exception e) {
                log.error(e.toString(), e);
            }
        }).start();
    }
}

说明:

1、通过@ConditionalOnProperty开关形式控制程序是否执行,后续此模块可以开发多个flink执行任务,通过开关的形式提交需要的job

2、通过springboot的@PostConstruct注解,让项目application启动时,自动执行job

3、用Thread线程执行任务提交,否则application启动时会一直flink执行中

4、日志打印,需要使用slf4j,跟flink自己依赖jar包打印日志保持一致,如此在flink集群执行时可以打印日志

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

private static final Logger log = LoggerFactory.getLogger(CalDeviceOfflineFunction.class);

5、kafka连接开启了登录验证,配置见application.yml。kafka登录验证server端配置见官网资料,后续有时间写个文章记录下

三、设备离线计算

/**
 * KeyedProcessFunction 为每个设备序列码维护一个state,并且会把间隔时间内(事件时间)内没有更新的设备序列码输出:
 * 对于每条记录,CalDeviceOfflineFunction 修改最后的时间戳。
 * 该函数还会在间隔时间内调用回调(事件时间)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
根据提供的引用内容,我们可以了解到Spring Boot是一个用于创建基于Spring的独立应用程序的框架,而Apache Flink是一个流处理框架。在Spring Boot中内嵌Flink可以让我们更方便地使用Flink进行流处理。同时,我们也可以将内嵌的Flink与外部的Flink集群进行整合,以便更好地利用Flink的分布式计算能力。 以下是实现Spring Boot内嵌Flink并对外部Flink集群进行整合的步骤: 1.在Spring Boot项目中添加Flink的依赖,例如: ```xml <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-streaming-java_2.11</artifactId> <version>1.12.2</version> </dependency> ``` 2.在Spring Boot项目中创建Flink的执行环境,例如: ```java StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); ``` 3.在Spring Boot项目中编写Flink的处理逻辑,例如: ```java DataStream<String> text = env.socketTextStream("localhost", 9999); DataStream<Integer> parsed = text.map(Integer::valueOf);DataStream<Integer> result = parsed.keyBy(x -> x % 10).sum(1); result.print(); ``` 4.将Spring Boot项目打包成jar包,并在外部Flink集群运行,例如: ```shell ./bin/flink run -c com.example.demo.Application /path/to/demo.jar ``` 5.在外部Flink集群中启动一个SocketTextStreamSource,例如: ```java DataStream<String> text = env.socketTextStream("localhost", 9999); ``` 6.在外部Flink集群中将SocketTextStreamSource与Spring Boot项目中的处理逻辑进行整合,例如: ```java DataStream<Integer> parsed = text.map(Integer::valueOf); DataStream<Integer> result = parsed.keyBy(x -> x % 10).sum(1); result.print(); ``` 7.启动外部Flink集群,例如: ```shell ./bin/start-cluster.sh ``` 8.启动SocketTextStreamSource,例如: ```shell ./bin/flink run -c org.apache.flink.streaming.examples.socket.SocketTextStreamWordCount /path/to/examples/streaming/SocketTextStreamWordCount.jar --port 9999 ``` 通过以上步骤,我们就可以实现Spring Boot内嵌Flink并对外部Flink集群进行整合了。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值