flink任务提交,查询,停止工具

flink任务提交器

1. 简介

因项目,需要在spring boot后台项目中集成flink任务提交,查询之类的功能,所有有了这个项目

这个项目,可以通过java api的形式,帮助你提交,查询,暂停flink任务,也可以构建和关闭flink yarn session集群。

主要通过restful接口和构建jobGraph实现

2. 支持以下的Flink运行模式

  • Flink local

  • Flink remote

  • Flink yarn session

  • Flink yarn per job

3. 主要类

3.1 FlinkInfo

根据Flink运行环境路径地址生成,提交和停止任务时使用

class FlinkInfo(val flinkHome: String) extends Serializable {



  private[this] lazy val FLINK_SCALA_VERSION_PATTERN: Pattern = Pattern.compile("^flink-dist_(.*)-(.*).jar$")


  lazy val fullVersion: String = s"${version}_$scalaVersion"


  /**
   * get scala version
   */
  lazy val scalaVersion: String = {
    val matcher: Matcher = FLINK_SCALA_VERSION_PATTERN.matcher(flinkDistJar.getName)
    matcher.matches()
    matcher.group(1)
  }


  /**
   * get Flink version
   */
  lazy val version: String = {
    val matcher: Matcher = FLINK_SCALA_VERSION_PATTERN.matcher(flinkDistJar.getName)
    matcher.matches()
    matcher.group(2)
  }


  /**
   * get all flink libs
   */
  lazy val flinkLib: File = {
    require(flinkHome != null, "flinkHome can not be null")
    require(new File(flinkHome).exists(), "flinkHome not exist")
    val lib = new File(s"$flinkHome/lib")
    require(lib.exists() && lib.isDirectory, s"$flinkHome/lib should be directory")
    lib
  }


  /**
   * yarn-ship content
   */
  lazy val flinkYarnShipFiles: List[String] = {
    List(flinkLib.toString,s"$flinkHome/plugins",s"$flinkHome/conf/log4j.properties")
  }


  /**
   * get flink distJar
   */
  lazy val flinkDistJar: File = {
    val distJar: Array[File] = flinkLib.listFiles().filter((_: File).getName.matches("flink-dist_.*\\.jar"))
    distJar match {
      case x if x.isEmpty =>
        throw new IllegalArgumentException(s"no flink-dist.jar in $flinkLib")
      case x if x.length > 1 =>
        throw new IllegalArgumentException(s"there are multiple flink-dist.jar in $flinkLib ")
      case _ =>
    }
    distJar.head
  }
}

3.2 ExecutionMode

执行模式枚举类

public enum ExecutionMode implements Serializable {


    LOCAL(0, "local"),

    REMOTE(1, "remote"),

    FLINK_YARN_SESSION(2, "yarn-session"),

    FLINK_YARN_PER_JOB(3,"yarn-per-job");

    private final Integer mode;

    private final String name;

    ExecutionMode(Integer mode, String name) {
        this.mode = mode;
        this.name = name;
    }
}

3.3 ResolveOrder

类加载策略枚举类

public enum ResolveOrder {
    /**
     * parent-first
     */
    PARENT_FIRST("parent-first", 0),
    /**
     * child-first
     */
    CHILD_FIRST("child-first", 1);

    private final String name;

    private final Integer value;

    ResolveOrder(String name, Integer value) {
        this.name = name;
        this.value = value;
    }
}

3.4 FlinkSubmitRequest

用于提交Flink任务

  • appName 任务名称

  • flinkJarPath jar包地址

  • savePoint 检查的路径

  • flinkParallelism 并行度

  • args 参数集合

case class FlinkSubmitRequest(flinkVersion: FlinkInfo,
                              executionMode: ExecutionMode,
                              resolveOrder: ResolveOrder,
                              appName: String,
                              mainClass: String,
                              flinkJarPath: String,
                              savePoint: String,
                              flinkParallelism: Int,
                              args: JavaList[String],
                              extraParameter: JavaMap[String, Any]) {


  lazy val effectiveAppName: String = if (this.appName == null) "flink-task" else this.appName


  lazy val supportTaskJarFile: File = {
        new File(flinkJarPath)
  }


  lazy val savepointRestoreSettings: SavepointRestoreSettings = {
    lazy val allowNonRestoredState: Boolean = Try(
      extraParameter.get(SavepointConfigOptions.SAVEPOINT_IGNORE_UNCLAIMED_STATE.key).toString.toBoolean).getOrElse(false)
    savePoint match {
      case sp if Try(sp.isEmpty).getOrElse(true) => SavepointRestoreSettings.none
      case sp => SavepointRestoreSettings.forPath(sp, allowNonRestoredState)
    }
  }
}

3.5 FlinkSubmitter

使用入口

object FlinkSubmitter {

  /**
   * submit flink task
   */
  def submit(submitRequest: FlinkSubmitRequest): FlinkSubmitResponse = {
    submitRequest.executionMode match {
      case ExecutionMode.LOCAL =>   LocalSubmit.submit(submitRequest)
      case ExecutionMode.REMOTE =>  RemoteSubmit.submit(submitRequest)
      case ExecutionMode.FLINK_YARN_SESSION => YarnSessionSubmit.submit(submitRequest)
      case ExecutionMode.FLINK_YARN_PER_JOB => YarnPerJobSubmit.submit(submitRequest)
      case _ => throw new UnsupportedOperationException(s"Unsupported ${submitRequest.executionMode} mode to submit flink task")
    }
  }

  /**
   * query flink task
   */
  def query(queryRequest: FlinkQueryRequest): FlinkQueryResponse = {
    queryRequest.executionMode match {
      case ExecutionMode.LOCAL  => LocalSubmit.query(queryRequest)
      case ExecutionMode.REMOTE => RemoteSubmit.query(queryRequest)
      case ExecutionMode.FLINK_YARN_SESSION => YarnSessionSubmit.query(queryRequest)
      case ExecutionMode.FLINK_YARN_PER_JOB => YarnPerJobSubmit.query(queryRequest)
      case _ => throw new UnsupportedOperationException(s"Unsupported ${queryRequest.executionMode} mode to query flink task")
    }
  }

  /**
   * stop flink task
   */
  def stop(stopRequest: FlinkStopRequest): FlinkStopResponse = {
    stopRequest.executionMode match {
      case ExecutionMode.LOCAL => LocalSubmit.stop(stopRequest)
      case ExecutionMode.REMOTE => RemoteSubmit.stop(stopRequest)
      case ExecutionMode.FLINK_YARN_SESSION => YarnSessionSubmit.stop(stopRequest)
      case ExecutionMode.FLINK_YARN_PER_JOB => YarnPerJobSubmit.stop(stopRequest)
      case _ => throw new UnsupportedOperationException(s"Unsupported ${stopRequest.executionMode} node to stop flink task")
    }
  }

  /**
   * deploy flink-yarn-session cluster
   */
  def deploy(flinkDeployRequest: FlinkDeployRequest): FlinkDeployResponse = {
    YarnSessionSubmit.deployYarnSession(flinkDeployRequest)
  }

  /**
   * shutdown flink-yarn-session cluster
   */
  def shutDown(flinkShutdownRequest: FlinkShutdownRequest): FlinkShutdownResponse = {
    YarnSessionSubmit.shutDownYarnSession(flinkShutdownRequest)
  }
}

4.测试用例(remote模式)

其余模式测试用例请参考工程里的代码

4.1 提交flink任务

public class FlinkSubmitTest {
    FlinkInfo flinkInfo = new FlinkInfo("/opt/flink-test");
    ResolveOrder resolveOrder = ResolveOrder.of(1);
    String appName = "flink-submit-test";
    String batchMainClass = "com.czl.submitter.FlinkTaskBatch";
    String jarPath = "./jar/flink-task-api-test-1.0.jar";
    List<String> param = Arrays.asList("1","2","3");
    HashMap<String,Object> extraMap = new HashMap<>();
    
    @Test
    void remoteTest() throws URISyntaxException {
        ExecutionMode remoteMode = ExecutionMode.of(1);
        URI activeAddress = new URI("http://ip:port/");
        extraMap.put(RestOptions.ADDRESS.key(), activeAddress.getHost());
        extraMap.put(RestOptions.PORT.key(), activeAddress.getPort());
        FlinkSubmitRequest remoteSubmit = new FlinkSubmitRequest(
                flinkInfo,
                remoteMode,
                resolveOrder,
                appName,
                batchMainClass,
                jarPath,
                null,
                1,
                param,
                extraMap);
        FlinkSubmitResponse submit = FlinkSubmitter.submit(remoteSubmit);
        System.out.println(submit.jobId());
    }
}

4.2 查询flink任务状态

主要参数

  • 执行模式
  • flink运行地址
  • jobId
public class FlinkQueryTest {
    @Test
    void remoteQuery() {
        String master = "http://ip:port";
        String jobId = "e0641a4f9f060961419531dd5233fe6c";
        FlinkQueryRequest request = new FlinkQueryRequest(ExecutionMode.REMOTE, master, jobId);
        FlinkQueryResponse query = FlinkSubmitter.query(request);
        System.out.println(query);
    }
}

4.3 停止flink任务

主要参数

  • savepoint路径
  • jobId
public class FlinkStopTest {
    FlinkInfo flinkInfo = new FlinkInfo("/opt/flink-test");
    String customSavePoint = "./sp/";
    Map<String, Object> extraParameter = new HashMap<>(0);

    @Test
    void remoteStop() throws URISyntaxException {
        ExecutionMode remote = ExecutionMode.REMOTE;
        URI activeAddress = new URI("http://ip:port/");
        extraParameter.put(RestOptions.ADDRESS.key(), activeAddress.getHost());
        extraParameter.put(RestOptions.PORT.key(), activeAddress.getPort());
        FlinkStopRequest request = new FlinkStopRequest(flinkInfo,
                remote,
                null,
                "e0641a4f9f060961419531dd5233fe6c",
                true,
                customSavePoint,
                false, extraParameter);
        FlinkStopResponse stop = FlinkSubmitter.stop(request);
        System.out.println(stop.savePointPath());
    }
}

4.4 部署和停止flink yarn session集群

主要参数

  • FlinkInfo
  • yarn name
public class YarnSessionTest {
    @Test
    void deploy(){
        FlinkInfo flinkInfo = new FlinkInfo("/opt/flink-test");
        FlinkDeployRequest deployRequest = new FlinkDeployRequest(flinkInfo, "czl-yarn-session-test");
        FlinkDeployResponse flinkDeployResponse = YarnSessionSubmit.deployYarnSession(deployRequest);
        System.out.println(flinkDeployResponse.address());
        System.out.println(flinkDeployResponse.clusterId());
    }


    @Test
    void shutdown(){
        FlinkInfo flinkInfo = new FlinkInfo("/opt/flink-test");
        FlinkShutdownRequest shutdownRequest = new FlinkShutdownRequest(flinkInfo, "application_1668191242058_0072");
        YarnSessionSubmit.shutDownYarnSession(shutdownRequest);
    }
}

5. 仓库地址

(https://github.com/Chenzhiling/flink-submitter-api)

6. 参考

从StreamX项目获得了相当多的思路,感谢

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值