flink源码解读--2 入口类CliFrontend

参考文章:  https://blog.csdn.net/weixin_43161811/article/details/103151644

从上篇文章,我们知道,flink脚本提交后,由CliFrontend main开始执行。

/** Submits the job based on the arguments. */

  public static void main(final String[] args) {

    // 1.打印基本的环境信息

    EnvironmentInformation.logEnvironmentInfo(LOG, "Command Line Client", args);

    // 2. find the configuration directory -- 获取配置文件目录:.../flink1.9.0/conf

    final String configurationDirectory = getConfigurationDirectoryFromEnv();

 // 3. load the global configuration -- 加载flink-conf.yaml中的全局配置转成Configuration对象

    final Configuration configuration =

        GlobalConfiguration.loadConfiguration(configurationDirectory);

// 4. load the custom command lines -- 加载用户输入的命令行、获取命令行参数

// customCommandLines添加org.apache.flink.yarn.cli.FlinkYarnSessionCli(configuration ,//configurationDirectory, //"y", "yarn")构造对象和new DefaultCLI(configuration)

    final List<CustomCommandLine<?>> customCommandLines =

        loadCustomCommandLines(configuration, configurationDirectory);

    try {

      //5.创建CliFrontend对象

      final CliFrontend cli = new CliFrontend(configuration, customCommandLines);

      //6.加载 SecurityConfiguration类,是flink全局安全配置

      SecurityUtils.install(new SecurityConfiguration(cli.configuration));

    

 //7.根据命令行参数进行匹配,运行程序,获取程序执行的运行码

      //调用CliFrontend的parseParameters方法, 解析命令行参数,运行具体的actionrun

      //cli.parseParameters(args)方法为最后的run(下述方法先做安全检查)

      int retCode = SecurityUtils.getInstalledContext().runSecured(() -> cli.parseParameters(args));

  

      //8.获取执行返回值,关闭提交程序

      System.exit(retCode);

    } catch (Throwable t) {

      final Throwable strippedThrowable =

          ExceptionUtils.stripException(t, UndeclaredThrowableException.class);

      LOG.error("Fatal error while running command line interface.", strippedThrowable);

      strippedThrowable.printStackTrace();

      System.exit(31);

    }

  }

步骤4构造FlinkYarnSessionCli明细过程:

/**

          * 初始化一个FlinkYarnSessionCli

          * @param configuration  全局的配置

          * @param configurationDirectory  全局的配置文件目录

          * @param shortPrefix   命令行参数的缩写前缀 y

          * @param longPrefix    命令行参数的展开前缀 yarn

          * @param acceptInteractiveInput 是否接受交互型输入 

          * @throws FlinkException

          */

public FlinkYarnSessionCli(

    Configuration configuration,

    String configurationDirectory,

    String shortPrefix,

    String longPrefix,

    boolean acceptInteractiveInput) throws FlinkException {

    // 1. 初始化参数

    super(configuration);

    this.configurationDirectory = Preconditions.checkNotNull(configurationDirectory);

    this.acceptInteractiveInput = acceptInteractiveInput;

    // 2. 创建命令行选项

    query = new Option(shortPrefix + "q", longPrefix + "query", false, "Display available YARN resources (memory, cores)");

    applicationId = new Option(shortPrefix + "id", longPrefix + "applicationId", true, "Attach to running YARN session");

    queue = new Option(shortPrefix + "qu", longPrefix + "queue", true, "Specify YARN queue.");

    shipPath = new Option(shortPrefix + "t", longPrefix + "ship", true, "Ship files in the specified directory (t for transfer)");

    flinkJar = new Option(shortPrefix + "j", longPrefix + "jar", true, "Path to Flink jar file");

    jmMemory = new Option(shortPrefix + "jm", longPrefix + "jobManagerMemory", true, "Memory for JobManager Container with optional unit (default: MB)");

    tmMemory = new Option(shortPrefix + "tm", longPrefix + "taskManagerMemory", true, "Memory per TaskManager Container with optional unit (default: MB)");

    container = new Option(shortPrefix + "n", longPrefix + "container", true, "Number of YARN container to allocate (=Number of Task Managers)");

    slots = new Option(shortPrefix + "s", longPrefix + "slots", true, "Number of slots per TaskManager");

    dynamicproperties = Option.builder(shortPrefix + "D")

        .argName("property=value")

        .numberOfArgs(2)

        .valueSeparator()

        .desc("use value for given property")

        .build();

    streaming = new Option(shortPrefix + "st", longPrefix + "streaming", false, "Start Flink in streaming mode");

    name = new Option(shortPrefix + "nm", longPrefix + "name", true, "Set a custom name for the application on YARN");

    zookeeperNamespace = new Option(shortPrefix + "z", longPrefix + "zookeeperNamespace", true, "Namespace to create the Zookeeper sub-paths for high availability mode");

    nodeLabel = new Option(shortPrefix + "nl", longPrefix + "nodeLabel", true, "Specify YARN node label for the YARN application");

    help = new Option(shortPrefix + "h", longPrefix + "help", false, "Help for the Yarn session CLI.");

    allOptions = new Options();

    allOptions.addOption(flinkJar);

    allOptions.addOption(jmMemory);

    allOptions.addOption(tmMemory);

    allOptions.addOption(container);

    allOptions.addOption(queue);

    allOptions.addOption(query);

    allOptions.addOption(shipPath);

    allOptions.addOption(slots);

    allOptions.addOption(dynamicproperties);

    allOptions.addOption(DETACHED_OPTION);

    allOptions.addOption(SHUTDOWN_IF_ATTACHED_OPTION);

    allOptions.addOption(YARN_DETACHED_OPTION);

    allOptions.addOption(streaming);

    allOptions.addOption(name);

    allOptions.addOption(applicationId);

    allOptions.addOption(zookeeperNamespace);

    allOptions.addOption(nodeLabel);

    allOptions.addOption(help);

    // 3. 加载默认的yarn配置文件

    this.yarnPropertiesFileLocation = configuration.getString(YarnConfigOptions.PROPERTIES_FILE_LOCATION);

    final File yarnPropertiesLocation = getYarnPropertiesLocation(yarnPropertiesFileLocation);

    // 4. 解析出yarn的配置参数

    yarnPropertiesFile = new Properties();

    if (yarnPropertiesLocation.exists()) {

        LOG.info("Found Yarn properties file under {}.", yarnPropertiesLocation.getAbsolutePath());

        try (InputStream is = new FileInputStream(yarnPropertiesLocation)) {

            yarnPropertiesFile.load(is);

        } catch (IOException ioe) {

            throw new FlinkException("Could not read the Yarn properties file " + yarnPropertiesLocation +

                                     ". Please delete the file at " + yarnPropertiesLocation.getAbsolutePath() + '.', ioe);

        }

        final String yarnApplicationIdString = yarnPropertiesFile.getProperty(YARN_APPLICATION_ID_KEY);

        if (yarnApplicationIdString == null) {

            throw new FlinkException("Yarn properties file found but doesn't contain a " +

                                     "Yarn application id. Please delete the file at " + yarnPropertiesLocation.getAbsolutePath());

        }

        try {

            // 尝试将id转化成ApplicationId

            yarnApplicationIdFromYarnProperties = ConverterUtils.toApplicationId(yarnApplicationIdString);

        }

        catch (Exception e) {

            throw new FlinkException("YARN properties contains an invalid entry for " +

                                     "application id: " + yarnApplicationIdString + ". Please delete the file at " +

                                     yarnPropertiesLocation.getAbsolutePath(), e);

        }

    } else {

        yarnApplicationIdFromYarnProperties = null;

    }

    // 5. 初始化yarn的配置

    this.yarnConfiguration = new YarnConfiguration();

}

步骤7 cli.parseParameters(args))代码明细:

/**
 * Parses the command line arguments and starts the requested action.
 *
 * @param args command line arguments of the client.
 * @return The return code of the program
 */
public int parseParameters(String[] args) {

   // check for action
   if (args.length < 1) {
      CliFrontendParser.printHelp(customCommandLines);
      System.out.println("Please specify an action.");
      return 1;
   }

   // get action 提取执行动作,比如run,list,cancel
   String action = args[0];

   // remove action from parameters  从参数中移除执行动作
   final String[] params = Arrays.copyOfRange(args, 1, args.length);

   try {
      // do action
      switch (action) {
         case ACTION_RUN:
            run(params);
            return 0;
         case ACTION_LIST:
            list(params);
            return 0;
         case ACTION_INFO:
            info(params);
            return 0;
         case ACTION_CANCEL:
            cancel(params);
            return 0;
         case ACTION_STOP:
            stop(params);
            return 0;
         case ACTION_SAVEPOINT:
            savepoint(params);
            return 0;
         case "-h":
         case "--help":
            CliFrontendParser.printHelp(customCommandLines);
            return 0;
         case "-v":
         case "--version":
            String version = EnvironmentInformation.getVersion();
            String commitID = EnvironmentInformation.getRevisionInformation().commitId;
            System.out.print("Version: " + version);
            System.out.println(commitID.equals(EnvironmentInformation.UNKNOWN) ? "" : ", Commit ID: " + commitID);
            return 0;
         default:
            System.out.printf("\"%s\" is not a valid action.\n", action);
            System.out.println();
            System.out.println("Valid actions are \"run\", \"list\", \"info\", \"savepoint\", \"stop\", or \"cancel\".");
            System.out.println();
            System.out.println("Specify the version option (-v or --version) to print Flink version.");
            System.out.println();
            System.out.println("Specify the help option (-h or --help) to get help on the command.");
            return 1;
      }
   } catch (CliArgsException ce) {
      return handleArgException(ce);
   } catch (ProgramParametrizationException ppe) {
      return handleParametrizationException(ppe);
   } catch (ProgramMissingJobException pmje) {
      return handleMissingJobException();
   } catch (Exception e) {
      return handleError(e);
   }
}

我们重点看下flink run 的逻辑,限于篇幅,在下一篇文章继续分析。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值