我试图在我的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.arguments
和spring.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
。
让我们知道这是否适合你,如果你有任何其他的想法让事情变得更简单。