flink自定义source、sink及从kafka消费数据到数据库的简单demo

一、简介

flink作为一个数据处理框架,其工作流程简单来说可以理解为:从数据源获取数据→处理数据→输出处理后的数据,source和sink则分别代表从数据源获取数据和输出数据,事实上flink本身提供了很多source和sink,但是在特殊使用场景时依然需要自定义source和sink,flink提供了较为统一的拓展方式,本例中从kafka消费数据就是使用flink官方提供的source,sink则为自定义拓展的写入数据到SQL server的sink。

二、添加依赖

在创建好的模板工程(创建模板工程方式参考https://blog.csdn.net/qq_37720936/article/details/104605758)中修改pom文件(注意第一行的注释,添加的依赖就加在它下面)


		
			org.apache.flink
			flink-connector-kafka_${scala.binary.version}
			${flink.version}
		
		
			com.microsoft.sqlserver
			mssql-jdbc
			7.4.1.jre8
		
		
			com.alibaba
			fastjson
			1.2.59
		

三、核心代码

话不多说,直接上代码

// 测试数据:{"id": "1","name": "z3","age": "23","time": 1589015374489}
//         {"id": "1","name": "l4","age": "23","time": 1589015374489}
public static void main(String[] args) throws Exception {
        // set up the streaming execution environment
        final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        Properties properties = new Properties();
        properties.setProperty("bootstrap.servers", "localhost:9092");

        FlinkKafkaConsumer consumer = new FlinkKafkaConsumer<>("test", new SimpleStringSchema(), properties);
        // 设置消费模式
        consumer.setStartFromGroupOffsets();
        DataStream stream = env
                .addSource(consumer)
                .filter(s -> {
                    try {
                        JSONObject.parseObject(s);
                    } catch (JSONException e) {
                        return false;
                    }
                    return !StrUtil.isBlank(s);
                });
        stream.addSink(new RichSinkFunction() {

            private Connection connection;

            @Override
            public void open(Configuration parameters) throws Exception {
                connection = DriverManager.getConnection("jdbc:sqlserver://ip", "userName", "password");
            }

            @Override
            public void invoke(String value, Context context) throws Exception {
                JSONObject jsonObject = JSON.parseObject(value);
                connection.createStatement().execute("INSERT database.schema.table (id, name, age, time) VALUES ('"
                        + jsonObject.getString("id") + "','"
                        + jsonObject.getString("name") + "','"
                        + jsonObject.getString("age") + "','"
                        + new Date(jsonObject.getLong("time")) + "')");
            }

            @Override
            public void close() throws SQLException {
                connection.close();
            }
        });
        env.execute();
    }

其中RichSinkFunction就是一个拓展sink的接口,flink中对source和sink提供了多个接口,source接口的继承关系如图,sink基本相同

flink自定义source、sink及从kafka消费数据到数据库的简单demo_第1张图片

open、invoke、close三个方法非常直观,就不多说了,中间用了一个filter算子过滤了一下空数据和非jsonObject格式的数据。

kafka和数据库的安装和使用就不多说了,这里使用的是本地搭的测试用单节点kafka,执行代码后(将pom文件中添加依赖那个地方上面两个依赖的provided注释掉可以在idea中直接运行代码)在kafka中相应topic中写入测试数据(测试数据中中文会乱码,暂时没找到原因,有大佬知道望告知,感激不尽),程序将自动同步到数据库中。

你可能感兴趣的:(学习笔记)