Zookeeper异常宕机重启失败分析

2021-03-12  本文已影响0人  明训

背景说明

一体机中使用了单机模式的zookeeper(开机自启服务),一体机经常会遇到断电重启的场景,在运行过程中偶现无法开机启动问题,再次断电重新启动可以正常启动

前置知识

kill -0 pid 不发送任何信号,但是系统会进行错误检查。所以经常用来检查一个进程是否存在,存在返回0;不存在返回1

The signals listed below may be available for use with kill. When known constant, numbers and default behavior are shown.Name Num Action Description 0 0 n/a exit code indicates if a signal may be sent

根因分析

脚本阅读

查看脚本zkServer.sh内容

case $1 in
start)
    echo  -n "Starting zookeeper ... "
    if [ -f $ZOOPIDFILE ]; then
      if kill -0 `cat $ZOOPIDFILE` > /dev/null 2>&1; then
         echo $command already running as process `cat $ZOOPIDFILE`.
         exit 0
      fi
    fi
    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
        exit 1
      fi
    else
      echo SERVER DID NOT START
      exit 1
    fi
    ;;

判断pid文件是否存在,存在如下两种情况:

  • 不存在则启动zookeeper服务

  • 存在则读取PID号发送信号0判断进程号是否活着,

    • 如果进程活着则啥也不做,打印日志already running as process pid
    • 如果进程死了则启动zookeeper服务,新进程号写入pid文件

查看脚本zkServer.sh内容

stop)
    echo -n "Stopping zookeeper ... "
    if [ ! -f "$ZOOPIDFILE" ]
    then
      echo "no zookeeper to stop (could not find file $ZOOPIDFILE)"
    else
      $KILL -9 $(cat "$ZOOPIDFILE")
      rm "$ZOOPIDFILE"
      echo STOPPED
    fi
    exit 0
    ;;

判断pid文件是否存在,存在如下两种情况:

  • 不存在则打印输出no zookeeper to stop (could not find file $ZOOPIDFILE)
  • 存在则kill -9 pid杀死进程并删除pid文件

查看脚本zkServer.sh内容

restart)
    shift
    "$0" stop ${@}
    sleep 3
    "$0" start ${@}
    ;;

先执行stop再执行start

原因说明

假设当兵设备异常断电关机,此时zookeepr的进程号是9966,此时pid的文件内容为9966,当一体机开机自启动时,如果已经有其他进程的进程号为9966时,此时zookeepr的启动脚本发现pid文件存在,且9966进程活着,则认为zookeepr已经正常启动,此时启动脚本啥事也不做只打印日志already running as process pid,此时zookeepr进程没有启动,紧接着skynet启动发现无法连接zookeeper,此时启动失败。

问题复现

  1. 启动zookeepr进程,然后kill -9强杀进程
  2. 寻找一个存活的进程并把进程号写入zookeeperpid文件中
  3. 启动zookeeper进程,发现zookeeper无法对外提供服务

通过以上步骤即可完成问题复现。

解决方案

一体机开机自启服务中使用restart命令即可。

单机模式

单机模式部署不需要新建myid文件和zoo.cfg配置项中添加

server.1=10.5.3.208:2888:3888

server.id=host:port:port : 表示了不同的zookeeper服务器的自身标识,作为集群的一部分,每一台服务器应该知道其他服务器的信息。用户可以从“server.id=host:port:port” 中读取到相关信息。在服务器的data(dataDir参数所指定的目录)下创建一个文件名为myid的文件,这个文件的内容只有一行,指定的是自身的id值。比如,服务器“1”应该在myid文件中写入“1”。这个id必须在集群环境中服务器标识中是唯一的,且大小在1~255之间。这一样配置中,zoo1代表第一台服务器的IP地址。第一个端口号(port)是从follower连接到leader机器的端口,第二个端口是用来进行leader选举时所用的端口。所以,在集群配置过程中有三个非常重要的端口:clientPort:2181、port:2888、port:3888。

这种模式有如下问题

建议单机模式下不新建myid文件并删除配置server.1

上一篇 下一篇

猜你喜欢

热点阅读