我正在尝试从在Docker上运行的Java应用程序内部启动一个进程(dstat系统工具)。 在我的本地计算机上运行应用程序,以下代码有效:
LOG.debug("Start DSTAT data collecting...");
try {
final ProcessBuilder processBuilder = new ProcessBuilder(DSTAT_COMMAND);
processBuilder.redirectErrorStream(true);
final Process process = processBuilder.start();
try (BufferedReader processOutputReader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
final String dstatResult = processOutputReader.lines()
.map(String::toString)
.collect(Collectors.joining(System.lineSeparator()));
final boolean exitCode = process.waitFor(10, TimeUnit.SECONDS);
LOG.debug("Dstat exit: {}", exitCode);
LOG.debug("Dstat output: {}", dstatResult);
}
但是从Docker开始,dstat-process没有输出,我的日志是:
2016-07-31 08:31:56.984 DEBUG 15 --- [lector-thread-1] i.thesis.collector.dstat.DstatCollector:启动DSTAT数据收集...... 2016-07-31 08:31:57.190 DEBUG 15 --- [lector-thread-1] i.thesis.collector.dstat.DstatCollector:Dstat exit:true 2016-07-31 08:31:57.190 DEBUG 15 --- [lector-thread-1] i.thesis.collector.dstat.DstatCollector:Dstat输出:
我也试过Runtime.getRuntime()。exec(“dstat”),导致挂起的原因
2016-07-30 19:18:41.199 DEBUG 11 --- [lector-thread-1] i.thesis.collector.dstat.DstatCollector : Start DSTAT data collecting...
dstat工具正确安装在容器上,我可以将docker exec放入,运行dstat命令并获得预期的输出。
为了完整性,Dockerfile:
FROM java:8-jre-alpine
RUN apk add --no-cache bash snappy
ARG FLINK_VERSION=1.0.3
ARG HADOOP_VERSION=27
ARG SCALA_VERSION=2.11
RUN set -x && \
apk --update add --virtual build-dependencies curl && \
# install dstat as collector source
apk add dstat --update-cache --repository http://dl-3.alpinelinux.org/alpine/edge/testing/ --allow-untrusted && \
curl -s $(curl -s https://www.apache.org/dyn/closer.cgi\?as_json\=1 | \
awk '/preferred/ {gsub(/"/,""); print $2}')flink/flink-${FLINK_VERSION}/flink-${FLINK_VERSION}-bin-hadoop${HADOOP_VERSION}-scala_${SCALA_VERSION}.tgz | \
tar xvz -C /usr/local/ && \
ln -s /usr/local/flink-$FLINK_VERSION /usr/local/flink && \
sed -i -e "s/echo \$mypid >> \$pid/echo \$mypid >> \$pid \&\& wait/g" /usr/local/flink/bin/flink-daemon.sh && \
apk del build-dependencies && \
rm -rf /var/cache/apk/*
ADD collector-client-app.jar /usr/local/collector/collector-client-app.jar
EXPOSE 9091
ENV FLINK_HOME /usr/local/flink
ENV PATH $PATH:$FLINK_HOME/bin
ENV FLINK_JMX_PORT 9999
ADD docker-entrypoint.sh $FLINK_HOME/bin/
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["sh", "-c"]
docker-entrypoint.sh:
if [ "$1" = "jobmanager" ]; then
echo "Starting Job Manager"
sed -i -e "s/jobmanager.rpc.address: localhost/jobmanager.rpc.address: `hostname -f`/g" $FLINK_HOME/conf/flink-conf.yaml
sed -i -e "s/taskmanager.numberOfTaskSlots: 1/taskmanager.numberOfTaskSlots: `grep -c ^processor /proc/cpuinfo`/g" $FLINK_HOME/conf/flink-conf.yaml
echo "env.java.opts: \"-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=$FLINK_JMX_PORT -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false \"" >> $FLINK_HOME/conf/flink-conf.yaml
echo "config file: " && grep '^[^\n#]' $FLINK_HOME/conf/flink-conf.yaml
$FLINK_HOME/bin/jobmanager.sh start cluster &
elif [ "$1" = "taskmanager" ]; then
echo "Starting Task Manager"
echo "config file: " && grep '^[^\n#]' $FLINK_HOME/conf/flink-conf.yaml
$FLINK_HOME/bin/taskmanager.sh start &
else
$@
fi
echo "Start collector client..."
java -Djava.security.egd=file:/dev/./urandom -jar /usr/local/collector/collector-client-app.jar
和docker-compose.yml
version: '2'
services:
flink-jobmanager:
image: flink
container_name: flink-jobmanager
ports:
- "8081:8081"
- "9999:9999"
- "9095:9091"
command: jobmanager
它可能与docker的进程-stdout-or-whatever处理有关,但我找不到任何有用的东西。
所以提前感谢任何想法或建议!