在IDEA下运行flink环境及web ui,debug调试

参考链接:https://www.galiglobal.com/blog/2021/20210130-Flink-setup.html
介绍
Apache Flink 是一个开源的、统一的流处理和批处理框架。与这些框架中的任何一个一样,开始使用它可能是一个挑战。即使有一个很好的入门或一个伟大的(和免费的)实践培训,也总是有关于如何开始、如何调试问题或如何在 IDE 中启动项目的问题。

在本文中,我总结了自从开始使用 Flink 以来我一直在写的一些笔记。如果 Flink 对你来说是新的东西,那么它很容易遵循。如果你已经是一个有经验的 Flink 开发人员,你可能会发现一些技巧很有用:访问 JMX 指标、分析等。

源代码在此 GitHub 存储库中可用。

安装 Flink
第一步是安装 Flink。这很简单,只需转到 Flink 下载页面并下载即可:

wget https://archive.apache.org/dist/flink/flink-1.12.0/flink-1.12.0-bin-scala_2.12.tgz
tar -zxvf flink-1.12.0-bin-scala_2.12.tgz
注意:最好创建一个指向 Flink 文件夹的变量 $FLINK_HOME。

启动群集:

$FLINK_HOME/bin/start-cluster.sh
您可以在浏览器中访问 Flink 网页仪表板。

我们最初不需要它,所以最好停止它:

$FLINK_HOME/bin/stop-cluster.sh
引导 Flink 作业
要引导项目,只需执行以下 Maven 命令:

mvn archetype:generate
-DarchetypeGroupId=org.apache.flink
-DarchetypeArtifactId=flink-quickstart-java
-DarchetypeVersion=1.12.0
-DgroupId=galiglobal
-DartifactId=flink-playground
-Dversion=0.1
-Dpackage=galiglobal.flink
-DinteractiveMode=false

cd flink-playground
该项目的结构非常简单:

.
├── pom.xml
└── src
└── main
├── java
│ └── galiglobal
│ └── flink
│ ├── BatchJob.java
│ └── StreamingJob.java
└── resources
└── log4j2.properties
我们将只关注.StreamingJob.java

在 IntelliJ IDEA 中导入并运行作业
我们将只介绍我最喜欢的Java IDE:IntelliJ IDEA。其他 IDE 应该以类似的方式工作。首先,在 IDE 中作为 maven 项目导入。您可以从命令行轻松完成此操作。

idea pom.xml
您可以使用 Linux/Windows 上的 Shift+F10 快捷方式将其作为普通 Java 应用程序执行。输出中应出现这样的错误:StreamingJob.java

线程“main”中的异常 java.lang.NoClassDefFoundError: org/apache/flink/streaming/api/environment/StreamExecutionEnvironment at galiglobal.flink.StreamingJob.main(StreamingJob.java:39) 原因: java.lang.ClassNotFoundException: org.apache.flink.streaming.api.environment.StreamExecutionEnvironment at java.net.URLClassLoader.findClass(URLClassLoader.java:382) at java.lang.ClassLoader.loadClass(ClassLoader.java:418) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:352) at java.lang.ClassLoader.loadClass(ClassLoader.java:351) …1 更多

这是 Flink 在 IDE 中运行的一个特殊问题:缺少一些依赖项。要解决此问题,请转到 -> -> -> 并在新字段中标记 。RunEdit ConfigurationModify optionsUse classpath of moduleInclude dependencies with “Provided” scope

Run configuration for Flink

重新运行作业,将显示一个新错误:

线程“main”中的异常 java.lang.IllegalStateException:流式拓扑中未定义运算符。无法执行。at org.apache.flink.streaming.api.environment.StreamExecutionEnvironment.getStreamGraphGenerator(StreamExecutionEnvironment.java:2000) at org.apache.flink.streaming.api.environment.StreamExecutionEnvironment.getStreamGraph(StreamExecutionEnvironment.java:1991) at org.apache.flink.streaming.api.environment.StreamExecutionEnvironment.getStreamGraph(StreamExecutionEnvironment.java:1976) atorg.apache.flink.streaming.api.environment.StreamExecutionEnvironment.execute(StreamExecutionEnvironment.java:1822) at galiglobal.flink.StreamingJob.main(StreamingJob.java:62)

是时候创建我们的 Flink 作业了。

开发我们的第一个 Flink 作业
让我们向项目添加一个名为 的新 Java 类:RandomLongSource

public class RandomLongSource extends RichParallelSourceFunction {

private volatile boolean cancelled = false;
private Random random;

@Override
public void open(Configuration parameters) throws Exception {
    super.open(parameters);
    random = new Random();
}

@Override
public void run(SourceContext<Long> ctx) throws Exception {
    while (!cancelled) {
        Long nextLong = random.nextLong();
        synchronized (ctx.getCheckpointLock()) {
            ctx.collect(nextLong);
        }
    }
}

@Override
public void cancel() {
    cancelled = true;
}

}
这个类只是生成一个无限系列的长数字来喂养我们的工作。

现在让我们修改以处理它并打印结果:StreamingJob.java

public class StreamingJob {
private SourceFunction source;
private SinkFunction sink;

public StreamingJob(SourceFunction<Long> source, SinkFunction<Long> sink) {
    this.source = source;
    this.sink = sink;
}

public void execute() throws Exception {
    StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

    DataStream<Long> LongStream =
        env.addSource(source)
            .returns(TypeInformation.of(Long.class));

    LongStream
        .map(new IncrementMapFunction())
        .addSink(sink);

    env.execute();
}

public static void main(String[] args) throws Exception {
    StreamingJob job = new StreamingJob(new RandomLongSource(), new PrintSinkFunction<>());
    job.execute();
}

public class IncrementMapFunction implements MapFunction<Long, Long> {

    @Override
    public Long map(Long record) throws Exception {
        return record + 1;
    }
}

}
注意:本课程来自实践培训。

如果你执行它,你会看到一个无限的长数字列表:


3> 3869376031196493001
12> 4265560998598976840
12> -7434045225389162179
1> 3964290136030554255
1> 8881056576399978883

Note: The 3>, 12>, 1> indicate which sub-task (i.e., thread) produced the output.

This is one of the most surprising things for Flink beginners: you don’t need a cluster to develop a Flink job, you can easily do it locally from your IDE and it works quite well.

There are some minor differences. For example, to access the Flink Web Dashboard you will need to add the following dependency to maven:

org.apache.flink flink-runtime-web_2.11 ${flink.version} And modify the variable with the following code:env

Configuration conf = new Configuration();
StreamExecutionEnvironment env = StreamExecutionEnvironment.createLocalEnvironmentWithWebUI(conf);
Note: credit goes to this StackOverflow answer.

Re-run the job and you should be able to access the Flink Web Dashboard and see your job running:

Flink Dashboard in local mode

Debug with breakpoints
在 IDE 中运行 Flink 作业的好处之一是能够像往常一样使用断点调试 Flink 作业。

Flink breakpoints

分析
您可以使用IntelliJ的另一个好处是分析以研究和提高工作绩效。有关详细信息,请参阅分析工具和 IntelliJ IDEA Ultimate。它适用于此设置:

Flink with IDEA profiler

您也可以使用 VisualVM 并使用 VisualVMLauncher 插件从 IntelliJ 启动它:

Flink with VisualVM

指标
Flink 生成通过不同接口(包括 JMX)公开的指标。有关更多信息,请参阅 Flink 指标。

要激活它,请将以下依赖项添加到:pom.xml

org.apache.flink flink-metrics-jmx_2.11 ${flink.version} 并更改变量以在 JMX 界面中公开指标:env

Properties props = new Properties();
props.put(“metrics.reporter.jmx.factory.class”, “org.apache.flink.metrics.jmx.JMXReporterFactory”);
Configuration conf = ConfigurationUtils.createConfiguration(props);
StreamExecutionEnvironment env = StreamExecutionEnvironment.createLocalEnvironmentWithWebUI(conf);
像往常一样运行作业,并在 VisualVM 中打开它。您需要安装 VisualVM MBeans 浏览器。指标应在“MBeans”选项卡中可用:

Flink metrics with VisualVM

伐木
让我们为我们的工作添加一些适当的日志记录。首先,将以下字段添加到:StreamingJob.java

private static final Logger LOG = LoggerFactory.getLogger(StreamingJob.class);
让我们删除 longStream 变量并创建一个包含一些日志消息的新变量:

LOG.debug(“Start Flink example job”);

DataStreamSink logTestStream = env.fromElements(0L, 1L, 2L)
.map(new IncrementMapFunction())
.addSink(sink);

LOG.debug(“Stop Flink example job”);
修改以使用 DEBUG 日志级别:src/main/resources/log4j2.properties

rootLogger.level = DEBUG
重新运行作业,应会看到新的日志跟踪:

Flink log messages

在本地运行作业时,日志级别非常详细,可能很难在 Flink 消息之间找到您的消息。让我们配置一下。再次编辑以添加以下行:src/main/resources/log4j2.properties

logger.flink.name = org.apache.flink
logger.flink.level = warn
重新运行作业,您应该只看到正确的日志消息。

测试
创建作业时最重要的事情之一是进行适当的测试,您可以从 IDE 运行。它会让你走得更快,因为你可以进行更改,运行测试并确保一切正常,就像更改之前一样。对更改的这种信心水平值得从一开始就编写测试的成本。

将以下依赖项添加到您的 :pom.xml

org.apache.flink flink-test-utils-junit ${flink.version} 将内部类移动到它们自己的文件中:IncrementMapFunction

Refactor Map function

现在让我们添加一个单元测试来测试此函数:src/test/java

public class StreamingJobTest {

@Test
public void testMap() throws Exception {
    IncrementMapFunction statelessMap = new IncrementMapFunction();
    Long out = statelessMap.map(1L);
    Assert.assertEquals(2L, out.longValue());
}

}

从 IDE 运行测试并查看结果:

Flink Unit Test

有关更多信息,请参阅 官方文档中的测试 Flink 作业。如何测试完成作业特别有趣。你也可以在官方的 Flink 训练测试中找到很好的例子。

在本地群集中运行,具有正确的日志记录
完成工作后,我们可以将其部署到本地群集中。第一步是为本地群集启用日志级别调试。编辑根级别并将其更改为调试:$FLINK_HOME/conf/log4j-cli.properties

rootLogger.level = DEBUG

再次启动群集:

$FLINK_HOME/bin/start-cluster.sh
我们需要修改源代码以使用远程执行环境,因此您应该再次替换变量:env

StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
编译我们的工作:

mvn clean package -Pbuild-jar
在本地群集中运行作业:

$FLINK_HOME/bin/flink run target/flink-playground-0.1.jar
它应获得类似于以下内容的输出:

作业已提交,作业ID bbea3ed5f5082a7267f85d92807b19dc 程序执行已完成 作业 具有作业ID bbea3ed5f5082a7267f85d92807b19dc
已完成

作业运行时间: 827 ms

如果检查日志,应会看到跟踪:

grep -R “example job” $FLINK_HOME/log/
摘要和后续步骤
在本文中,我们介绍了在本地环境中使用 Apache Flink 的基础知识和一些典型陷阱。在您的设置中投入时间以提高工作效率并获得愉快的工作体验非常重要。您花在改进工作流程上的每一分钟都将在未来得到回报。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值