Java整合Flink流式处理从Kafka获取的数据

上次的例子https://blog.csdn.net/xxkalychen/article/details/117149540?spm=1001.2014.3001.5502将Flink的数据源设置为Socket,只是为了测试提供流式数据。生产中一般不会这么用,标准模型是从消息队列获取流式数据。Flink提供了跟kafka连接的封装,我们只需要一点小小的改动就可以实现从Kafka获取数据。

不过修改之前,需要搭建一个Kafka服务器。具体搭建过程这里不做详述。现在我们来修改程序。

一、添加pom依赖。

<dependency>
    <groupId>org.apache.flink</groupId>
    <artifactId>flink-connector-kafka_2.12</artifactId>
    <version>${flink.version}</version>
</dependency>

其版本要和flink保持一致。

二、修改测试类。我们另外创建一个测试类。

package com.chris.flink;

import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.api.common.serialization.SimpleStringSchema;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer;
import org.apache.flink.util.Collector;

import java.util.Arrays;
import java.util.Properties;

/**
 * @author Chris Chan
 * Create on 2021/5/22 7:23
 * Use for:
 * Explain: Flink流式处理从Kafka获取的数据
 */
public class KafkaStreamTest {
    public static void main(String[] args) throws Exception {
        new KafkaStreamTest().execute(args);
    }

    private void execute(String[] args) throws Exception {
        //获取执行环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.setParallelism(1);

        //配置kafka
        Properties properties = new Properties();
        properties.put("bootstrap.servers", "flink.chris.com:9092");
        properties.put("group.id", "flink_group_1");
        //从socket获取数据
        DataStreamSource<String> streamSource = env.addSource(new FlinkKafkaConsumer<String>("topic_flink", new SimpleStringSchema(), properties));

        //wordcount计算
        SingleOutputStreamOperator<Tuple2<String, Integer>> operator = streamSource.flatMap(new FlatMapFunction<String, Tuple2<String, Integer>>() {
            /**
             * map计算
             * @param value 输入数据 用空格分隔的句子
             * @param out map计算之后的收集器
             * @throws Exception
             */
            @Override
            public void flatMap(String value, Collector<Tuple2<String, Integer>> out) throws Exception {
                //用空格分隔为单词
                String[] words = value.split(" ");
                //统计单词使用频次,放入收集器
                Arrays.stream(words)
                        //洗去前后空格
                        .map(String::trim)
                        //过滤掉空字符串
                        .filter(word -> !"".equals(word))
                        //加入收集器
                        .forEach(word -> out.collect(new Tuple2<>(word, 1)));
            }
        })
                //按照二元组第一个字段word分组,把第二个字段统计出来
                .keyBy(0).sum(1);
        operator.print();

        env.execute();
    }
}

修改的部分也是四行。

//配置kafka
Properties properties = new Properties();
properties.put("bootstrap.servers", "flink.chris.com:9092");
properties.put("group.id", "flink_group_1");
//从socket获取数据
DataStreamSource<String> streamSource = env.addSource(new FlinkKafkaConsumer<String>("topic_flink", new SimpleStringSchema(), properties));

配置一下Kafka的服务器和消费者分组,然后创建消费者,从Kafka获取数据。

三、测试。

测试之前,首先启动zookeeper和kafka,并且让kafka处于主题消息生产发送状态。

nohup /var/app/kafka_2.13-2.8.0/bin/zookeeper-server-start.sh /var/app/kafka_2.13-2.8.0/config/zookeeper.properties > /var/app/kafka_2.13-2.8.0/logs/zookeeper.log 2>&1 &
nohup /var/app/kafka_2.13-2.8.0/bin/kafka-server-start.sh /var/app/kafka_2.13-2.8.0/config/server.properties > /var/app/kafka_2.13-2.8.0/logs/kafka.log 2>&1 &
/var/app/kafka_2.13-2.8.0/bin/kafka-console-producer.sh --broker-list localhost:9092 --topic topic_flink

运行程序,在kafka输入数据。

查看后台。

提交到集群执行效果。

可是并不成功,原因很简单,Flink集群只包含Flink基本必须的包,对于工程中使用的其他包是不包含的,所以会出现找不到相关类的异常。因此我们还需要配置maven的assmbly插件,采用完全打包的方式。

在pom中添加

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>

        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <configuration>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
                <archive>
                    <manifest>
                        <mainClass>com.chris.flink.KafkaStreamTest</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>

这个配置指定了一个主类。

然后打包。

mvn clean package assembly:assembly

打包过程耗时比较长,因为这种方法需要把依赖包全都打包进去。打包完成之后,在target下有个

flink-demo-20210522-1.0.0-SNAPSHOT-jar-with-dependencies.jar

这就是我们需要的完整jar包了。

把这个包从页面传上去,创建任务时发现主类已经填好了,就是因为我们已经在清单中配置了一个主类。如果要使用其他主类,就修改。

提交之后,稍等一会,就处于运行状态,等待数据。

我们在kafka输入数据。

查看线上标准输出。

测完之后,发现之前有个小担心不存在。原来在测试storm时,本地需要的基础包在线上不能有,否则会冲突,所以不停在改pom中的作用域,很是折腾人。原以为flink也会出现这种问题,结果没有,轻松好多。

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用 Java 编程语言来实现 Flink 实时处理 Kafka。下面是一个简单的示例代码: ```java 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.streaming.connectors.kafka.FlinkKafkaConsumer; import java.util.Properties; public class FlinkKafkaExample { public static void main(String[] args) throws Exception { // 创建 Flink 执行环境 StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); // 设置 Kafka 连接参数 Properties properties = new Properties(); properties.setProperty("bootstrap.servers", "localhost:9092"); properties.setProperty("group.id", "flink-consumer"); // 创建 Kafka 数据FlinkKafkaConsumer<String> kafkaConsumer = new FlinkKafkaConsumer<>("topic", new SimpleStringSchema(), properties); DataStream<String> kafkaStream = env.addSource(kafkaConsumer); // 在数据流上进行处理逻辑 DataStream<String> processedStream = kafkaStream.map(str -> "Processed: " + str); // 打印处理后的结果 processedStream.print(); // 执行任务 env.execute("Flink Kafka Example"); } } ``` 在上述代码中,我们使用 `FlinkKafkaConsumer` 连接到 Kafka 主题,将 Kafka 中的数据流添加到 Flink 的执行环境中。然后,我们对数据流进行处理,并将处理后的结果打印出来。最后,通过调用 `env.execute()` 来执行任务。 请确保在运行代码之前,您已经正确配置了 Kafka 的连接参数,并将相关的 FlinkKafka 依赖项添加到您的项目中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值