弹簧引导纱-传递命令行参数



我试图在我的Spring Boot Yarn应用程序中传递命令行参数,并且遇到了困难。我知道我可以在yml文档spring.yarn.appmaster.launchcontext.arguments中设置这些,但如何从命令行设置呢?如java -jar MyYarnApp.jar {arg0} {arg1},并从我的@YarnContainer访问它?

我发现@YarnProperties映射到spring.yarn.appmaster.launchcontext.arguments,但我想从命令行设置它们,而不是在yml

当你发现spring.yarn.client.launchcontext.argumentsspring.yarn.appmaster.launchcontext.arguments时,你非常接近这一点。我们没有设置自动将所有命令行参数从客户端传递到appmaster,然后将它们传递到容器启动上下文。不确定我们是否想要这样做,因为您肯定想要控制YARN容器启动上下文发生的事情。然后,使用客户端的用户可能会沿着食物链传递非法参数。

说了这么多,让我们看看我们可以用简单的单项目YARN应用指南做些什么。

我们仍然需要使用这些启动上下文参数来定义我们的命令行参数,以基本映射内容如何从客户端传递到appmaster到容器。

在application.yml:

中添加的内容
spring:
    yarn:
        client:
            launchcontext:
                arguments:
                    --my.appmaster.arg1: ${my.client.arg1:notset1}
        appmaster:
            launchcontext:
                arguments:
                    --my.container.arg1: ${my.appmaster.arg1:notset2}

Application类中修改HelloPojo:

@YarnComponent
@Profile("container")
public static class HelloPojo {
    private static final Log log = LogFactory.getLog(HelloPojo.class);
    @Autowired
    private Configuration configuration;
    @Value("${my.container.arg1}")
    private String arg1;
    @OnContainerStart
    public void onStart() throws Exception {
        log.info("Hello from HelloPojo");
        log.info("Container arg1 value is " + arg1);
        log.info("About to list from hdfs root content");
        FsShell shell = new FsShell(configuration);
        for (FileStatus s : shell.ls(false, "/")) {
            log.info(s);
        }
        shell.close();
    }
}

注意我是如何添加arg1并使用@Value将其与my.container.arg1进行映射的。我们可以使用@ConfigurationProperties@Value,这是正常的Spring和Spring Boot功能,在Boot的参考文档中有更多关于如何使用它们的信息。

你可以修改AppIT单元测试:

ApplicationInfo info = submitApplicationAndWait(Application.class, new String[]{"--my.client.arg1=arg1value"});

并运行带有测试的构建

./gradlew clean build

或者只构建它而不运行test:

./gradlew clean build -x test

,然后提交到一个真正的hadoop集群与您的my.client.arg1

java -jar build/libs/gs-yarn-basic-single-0.1.0.jar --my.client.arg1=arg1value

无论哪种方式,您都可以在容器日志中看到arg1value日志:

[2014-07-18 08:49:09.802] boot - 2003  INFO [main] --- ContainerLauncherRunner: Running YarnContainer with parameters [--spring.profiles.active=container,--my.container.arg1=arg1value]
[2014-07-18 08:49:09.806] boot - 2003  INFO [main] --- Application$HelloPojo: Container arg1 value is arg1value

使用${my.client.arg1:notset1}格式还允许在用户省略my.client.arg1时自动定义默认值notset1。我们正在Spring Application Context中工作,这里由Spring Boot编排,所以那里的所有好东西都在您的处置中

如果你需要更精确地控制那些面向用户的参数(使用args4j, jopt等),那么你需要为客户端/appmaster/容器顺序创建一个单独的code/jar来创建一个自定义的客户端主方法。所有其他的Spring YARN入门指南几乎都是使用多项目构建的,所以看看这些。例如,如果您只想拥有第一个和第二个参数值,而不需要在命令行中使用完整的--my.client.arg1=arg1value

让我们知道这是否适合你,如果你有任何其他的想法让事情变得更简单。

最新更新