public static void main(final String[] args) {
... ...
final List<CustomCommandLine> customCommandLines = loadCustomCommandLines(
configuration,
configurationDirectory);
... ...
final CliFrontend cli = new CliFrontend(
configuration,
customCommandLines);
... ...
}

这里依次添加了 Generic、YarnDefault三种命令行客户端(后面根据isActive()按顺序选择):

public static List<CustomCommandLine> loadCustomCommandLines(Configuration configuration, String configurationDirectory) {
List<CustomCommandLine> customCommandLines = new ArrayList<>();
customCommandLines.add(new GenericCLI(configuration, configurationDirectory));

// Command line interface of the YARN session, with a special initialization here
// to prefix all options with y/yarn.
final String flinkYarnSessionCLI = "org.apache.flink.yarn.cli.FlinkYarnSessionCli";
try {
customCommandLines.add(
loadCustomCommandLine(flinkYarnSessionCLI,
configuration,
configurationDirectory,
"y",
"yarn"));
} catch (NoClassDefFoundError | Exception e) {
final String errorYarnSessionCLI = "org.apache.flink.yarn.cli.FallbackYarnSessionCli";
try {
LOG.info("Loading FallbackYarnSessionCli");
customCommandLines.add(
loadCustomCommandLine(errorYarnSessionCLI, configuration));
} catch (Exception exception) {
LOG.warn("Could not load CLI class {}.", flinkYarnSessionCLI, e);
}
}

// Tips: DefaultCLI must be added at last, because getActiveCustomCommandLine(..) will get the
// active CustomCommandLine in order and DefaultCLI isActive always return true.
customCommandLines.add(new DefaultCLI(configuration));

return customCommandLines;
}

在run()里面,进行客户端的选择:

protected void run(String[] args) throws Exception {
... ...
final CustomCommandLine activeCommandLine =
validateAndGetActiveCommandLine(checkNotNull(commandLine));
... ...
}
public CustomCommandLine validateAndGetActiveCommandLine(CommandLine commandLine) {
... ...
for (CustomCommandLine cli : customCommandLines) {
... ...
//在FlinkYarnSessionCli为active时优先返回FlinkYarnSessionCli。
//对于DefaultCli,它的isActive方法总是返回true。
if (cli.isActive(commandLine)) {
return cli;
}
}
... ...
}

FlinkYarnSessionCli.java => Yarn客户端isActive的判断逻辑:

public boolean isActive(CommandLine commandLine) {
final String jobManagerOption = commandLine.getOptionValue(addressOption.getOpt(), null);
// 是否指定为per-job模式,即指定”-m yarn-cluster”; ID = "yarn-cluster"
final boolean yarnJobManager = ID.equals(jobManagerOption);
// 是否存在flink在yarn的appID,即yarn-session模式是否启动
final boolean hasYarnAppId = commandLine.hasOption(applicationId.getOpt())
|| configuration.getOptional(YarnConfigOptions.APPLICATION_ID).isPresent();
// executor的名字为 "yarn-session" 或 "yarn-per-job"
final boolean hasYarnExecutor = YarnSessionClusterExecutor.NAME.equals(configuration.get(DeploymentOptions.TARGET))
|| YarnJobClusterExecutor.NAME.equals(configuration.get(DeploymentOptions.TARGET));
//
return hasYarnExecutor || yarnJobManager || hasYarnAppId || (isYarnPropertiesFileMode(commandLine) && yarnApplicationIdFromYarnProperties != null);
}