最近使用zookeeper發現, 首次啓動zookeeper時, 都會遇到一個錯誤:spa
$ bin/zkServer.sh startorm
JMX enabled by defaultserver
Using config: /home/nauhcud/workspace/zookeeper/zookeeper/bin/../conf/zoo.cfg進程
Starting zookeeper ... bin/zkServer.sh: 162: cannot create /tmp/zookeeper/zookeeper_server.pid: Directory nonexistentit
FAILED TO WRITE PIDzookeeper
查看進程發現zookeeper進程存在, 並能夠正常使用. dataDir "/tmp/zookeeper/" 也在. file
kill掉zookeeper進程從新啓動, 一切正常.im
刪掉dataDir, 問題依舊.腳本
查看啓動腳本, 發現start邏輯以下:word
start)
...
nohup $JAVA "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" "-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}" \
-cp "$CLASSPATH" $JVMFLAGS $ZOOMAIN "$ZOOCFG" > "$_ZOO_DAEMON_OUT" 2>&1 < /dev/null &
if [ $? -eq 0 ]
then
if /bin/echo -n $! > "$ZOOPIDFILE"
then
sleep 1
echo STARTED
else
echo FAILED TO WRITE PID #這句說明寫入Pid出現了問題
exit 1
fi
...
縱觀整個腳本, dataDir沒有出現, 所以, dataDir應該是zookeeper進程內部創建的, 而且有必定延遲, 所以將zookeeper進程id寫入到dataDir下的pidfile時, dataDir尚未創建好, 所以就出現了上述狀況.
解決辦法很簡單, 在寫入pid以前先判斷一下datadir是否存在, 讓zookeeper有時間作完初始化, 而後再將pid寫入便可.
start)
...
nohup $JAVA "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" "-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}" \
-cp "$CLASSPATH" $JVMFLAGS $ZOOMAIN "$ZOOCFG" > "$_ZOO_DAEMON_OUT" 2>&1 < /dev/null &
zkpid=$!;
if [ $? -eq 0 ]
then
while [ ! -d `dirname $ZOOPIDFILE` ]
do
sleep 1;
done
if /bin/echo -n $zkpid > "$ZOOPIDFILE"
then
sleep 1
echo STARTED
else
echo FAILED TO WRITE PID
exit 1
fi
...