关于HaProxy更改PID LOCK文件路径导致haproxy.init不可用问题处理

文章首发站点:OpensGalaxy.com

最近更新了haproxy版本到了1.6.9,也是最新的稳定版本。在部署时我更改了pid和lock文件的默认存储路径,在使用1.6.9自带的haproxy.init 控制服务启停时,出现了问题。

haproxy 安装简述

下载 haproxy http://www.haproxy.org/download/1.6/src/haproxy-1.6.9.tar.gz

cd /root/
tar -zxvf haproxy-1.6.9.tar.gz
make TARGET=linux26
make install

haproxy执行程序默认位置是 /usr/local/sbin/haproxy

mkdir -p /usr/local/haproxy/conf
mkdir -p /usr/local/haproxy/sbin
cp /usr/local/sbin/haproxy /usr/local/haproxy/sbin
cp /root/haproxy-1.6.9/examples/option-http_proxy.cfg usr/local/haproxy/conf/haproxy.cfg ## 也可以自己手动建立一个,然后添加配置进去。
cp /root/haproxy-1.6.9/examples/haproxy.init /etc/init.d/haproxy

haproxy.cfg 配置文件全局部分

[root@CMHAProxy02 conf]# cat haproxy.cfg 
global
        log 127.0.0.1 local6
        maxconn 65535
        chroot /usr/local/haproxy
        uid 99
        gid 99
        daemon
        nbproc 1
        description haproxy
        pidfile /usr/local/haproxy/haproxy.pid  ### 我更改了pid文件路径。

defaults
        log global
        mode http
        balance roundrobin
        option httplog
        option forceclose
        option dontlognull
        option redispatch
        option abortonclose
        log 127.0.0.1 local6
        timeout connect 5000ms
        timeout client 30000ms
        timeout server 30000ms

拷贝haproxy.init文件到/etc/init.d下:

[root@CMHAProxy02 ~]# cp /root/haproxy-1.6.9/examples/haproxy.init /etc/init.d/haproxy

使用status、stop参数执行,报错信息如下:

[root@CMHAProxy02 haproxy]# /etc/init.d/haproxy status
haproxy 已死,但是 subsys 被锁

[root@CMHAProxy02 subsys]# /etc/init.d/haproxy stop
Shutting down haproxy:                                     [失败]

发现status 和 stop 都不能正常使用,虽然haproxy.pid 和haproxy.lock也都正常生成,于是开始追查问题原因。

cat /etc/init.d/haproxy  

[root@CMHAProxy02 haproxy]# cat /etc/init.d/haproxy |more
#!/bin/sh
#
# chkconfig: - 85 15
# description: HA-Proxy is a TCP/HTTP reverse proxy which is particularly suite
d \
#              for high availability environments.
# processname: haproxy
# config: /etc/haproxy/haproxy.cfg
# pidfile: /var/run/haproxy.pid

# Script Author: Simon Matter <simon.matter@invoca.ch>
# Version: 2004060600

# Source function library.
if [ -f /etc/init.d/functions ]; then
  . /etc/init.d/functions
elif [ -f /etc/rc.d/init.d/functions ] ; then
  . /etc/rc.d/init.d/functions
else
  exit 0
fi

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ ${NETWORKING} = "no" ] && exit 0

# This is our service name
BASENAME=`basename $0`
if [ -L $0 ]; then
  BASENAME=`find $0 -name $BASENAME -printf %l`
  BASENAME=`basename $BASENAME`
fi

BIN=/usr/local/haproxy/sbin/$BASENAME ##haproxy执行文件路径

CFG=/usr/local/$BASENAME/conf/$BASENAME.cfg  ## 配置文件路径
[ -f $CFG ] || exit 1

PIDFILE=/usr/local/haproxy/$BASENAME.pid  ##我修改了该haproxy pid 文件的路径
LOCKFILE=/usr/local/haproxy/$BASENAME  ## 也修改了lock 文件路径

RETVAL=0

start() {
  quiet_check
  if [ $? -ne 0 ]; then
    echo "Errors found in configuration file, check it with '$BASENAME check'."
    return 1
  fi

  echo -n "Starting $BASENAME: "
  daemon $BIN -D -f $CFG -p $PIDFILE
  RETVAL=$?
  echo
  [ $RETVAL -eq 0 ] && touch $LOCKFILE
  return $RETVAL
}

stop() {
  echo -n "Shutting down $BASENAME: "
  killproc $BASENAME -USR1
  RETVAL=$?
  echo
  [ $RETVAL -eq 0 ] && rm -f $LOCKFILE
  [ $RETVAL -eq 0 ] && rm -f $PIDFILE
  return $RETVAL
}

restart() {
  quiet_check
  if [ $? -ne 0 ]; then
    echo "Errors found in configuration file, check it with '$BASENAME check'."
    return 1
  fi
  stop
  start
}

reload() {
  if ! [ -s $PIDFILE ]; then
    return 0
  fi

  quiet_check
  if [ $? -ne 0 ]; then
    echo "Errors found in configuration file, check it with '$BASENAME check'."
    return 1
  fi
  $BIN -D -f $CFG -p $PIDFILE -sf $(cat $PIDFILE)
}

check() {
  $BIN -c -q -V -f $CFG
}

quiet_check() {
  $BIN -c -q -f $CFG
}

rhstatus() {
  status $BASENAME
}

condrestart() {
  [ -e $LOCKFILE ] && restart || :
}

# See how we were called.
case "$1" in
  start)
    start
    ;;
  stop)
    stop
    ;;
  restart)
    restart
    ;;
  reload)
    reload
    ;;
  condrestart)
    condrestart
    ;;
  status)
    rhstatus
    ;;
  check)
    check
    ;;
  *)
    echo $"Usage: $BASENAME {start|stop|restart|reload|condrestart|status|check
}"
    exit 1
esac

exit $?

这里我注意到,haproxy.init一开始就引用了/etc/init.d/functions这个shell公共函数

if [ -f /etc/init.d/functions ]; then
  . /etc/init.d/functions
elif [ -f /etc/rc.d/init.d/functions ] ; then
  . /etc/rc.d/init.d/functions
else
  exit 0
fi

而haproxy.init关于stop、status等函数中也调用了该公共函数的 killproc和status函数。

stop() {
  echo -n "Shutting down $BASENAME: "
  killproc $BASENAME -USR1
  RETVAL=$?
  echo
  [ $RETVAL -eq 0 ] && rm -f $LOCKFILE
  [ $RETVAL -eq 0 ] && rm -f $PIDFILE
  return $RETVAL
}


rhstatus() {
  status $BASENAME
}

查看/etc/init.d/functions,关于pid的这里已经把pid_file默认变量赋值写好了

__pids_var_run() {
        local base=${1##*/}
        local pid_file=${2:-/var/run/$base.pid} 
        ## 这里是如果$2为空,那么就将/var/run/$base.pid赋值给pid_file  

关于lock的

if [ -f /var/lock/subsys/${lock_file} ]; then
    echo $"${base} dead but subsys locked"
    return 2
fi
## 如果找不到 lock文件,就会报  “${base} dead but subsys locked”

所以如果更改了PID和LOCK文件的路径,就会引起之前我碰到的问题了。那么如果避免这样的问题呢?

1、就按照脚本的路径设置pid和lock文件位置,也就是默认位置。

2、如果非要更改这两个文件的位置,那么可以复制一个functions,命名为hafunctions,然后在haproxy中重新引用新的hafuntions公共函数,然后更改该公共函数中上文我提到的pid lock文件位置。(为什么要新复制一个公共函数呢,因为除了这个程序,init.d中的其他程序也引用了该函数,如果改动了,会影响其他程序。)

发表评论