Flink的一个常见小坑:missing parameter type(从源码分析为啥换一个导入就可以)

1 原因分析

        这个报错一般会有两种情况:

  • map过程中存在的POJO类没有定义完善,缺少公有构造函数定义等
  • 使用Scala编码时,Flink接入的Kafka数据,不能使用幂名函数进行操作,只能自定义函数进行对DS的处理

2 对应的解决办法

2.1 对POJO类进行完整定义

        使用@Lombok对class进行注解

2.2 查看是否StreamingExecutionEnviroment导错

JAVA程序对应的Enviroment导入:

import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;

Scala程序对应的Enviromment导入:

import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment

3 那为什么引用不同的类就会报错呢

底层的原因是什么呢?我带着这个好奇心去源码里面看了一下。

入口函数:

 val environment: StreamExecutionEnvironment = StreamExecutionEnvironment
      .createLocalEnvironmentWithWebUI()

函数点击进去看到函数签名(进入到org.apache.flink.streaming.api.scala.StreamExecutionEnvironment):

  /**
   * Creates a [[StreamExecutionEnvironment]] for local program execution that also starts the
   * web monitoring UI.
   *
   * The local execution environment will run the program in a multi-threaded fashion in
   * the same JVM as the environment was created in. It will use the parallelism specified in the
   * parameter.
   *
   * If the configuration key 'rest.port' was set in the configuration, that particular
   * port will be used for the web UI. Otherwise, the default port (8081) will be used.
   *
   * @param config optional config for the local execution
   * @return The created StreamExecutionEnvironment
   */
  @PublicEvolving
  def createLocalEnvironmentWithWebUI(config: Configuration = null): StreamExecutionEnvironment = {
    val conf: Configuration = if (config == null) new Configuration() else config
    //调用JAVAEnv创建一个JavaEnv返回。
    //那么这个错误会和哪里有关系呢?
    new StreamExecutionEnvironment(JavaEnv.createLocalEnvironmentWithWebUI(conf))
  }

点进来一看,这里没有什么问题呀,这里也确实没有问题。那么问题在哪呢

真正的问题根源:

 /**
   * Create a DataStream using a user defined source function for arbitrary
   * source functionality. By default sources have a parallelism of 1. 
   * To enable parallel execution, the user defined source should implement 
   * ParallelSourceFunction or extend RichParallelSourceFunction. 
   * In these cases the resulting source will have the parallelism of the environment. 
   * To change this afterwards call DataStreamSource.setParallelism(int)
   *
   */
  def addSource[T: TypeInformation](function: SourceFunction[T]): DataStream[T] = {
    require(function != null, "Function must not be null.")
    //寻找闭包函数,这个是常规操作
    val cleanFun = scalaClean(function)
    //重头戏是这个隐式的implicitly[TypeInformation[T]]
    val typeInfo = implicitly[TypeInformation[T]]
    asScalaStream(javaEnv.addSource(cleanFun, typeInfo))
  }

implicit转换,我肤浅的理解是找到对应的定义。例如这个例子当中的TypeInformation[T],就是找到对应的TypeInfo,然后传递。

4、揭开谜底

那么谜底是啥呢,谜底就是Flink自己定义好了好多TypeInfo等着套,或者说定义了一个类型完备的TypeInfo集合(因为我现在还没有遇到没匹配到的,遇到了我再更新这句话)。

下面这张图片里面包含了所有的TypeInfo实现类。如果是下次引入类型不对,可以进去到源码看看哪里对应不上。

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大锤爱编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值