南天一柱 发表于 2018-11-10 10:15:46

关于nginx信号控制的“故障”案例

  关于nginx信号控制的“故障”案例
  最近几天发现nginx的日志老切割不成功,遂来查找问题。
  最开始以为是logrotate的脚本问题,遂手动切割,运行以下的命令
  


[*]logrotate -vf /etc/logrotate.d/nginx
  

  发现运行这个是没有问题的,终于,在service nginx restart后,发现了问题
  问题是在用service nginx restart后,nginx.pid文件才会自动消失,于是,仔细检查脚本,发现一些端倪啊,一个字眼出现了
  


[*]killproc $prog -QUIT
  

  -QUIT从容关闭,也就是说这个进程是慢慢关闭的,不是立即关闭的,于是验证。如图
http://blog.51cto.com/attachment/201208/184202649.png
  查看进程如下
http://blog.51cto.com/attachment/201208/184246137.png
  可以看到,nginx正在shutdown之中,但没有一下子全部关闭了。
http://blog.51cto.com/attachment/201208/184329739.png
  随着时间的推移,nginx老的进程在继续关闭中……
http://blog.51cto.com/attachment/201208/184837883.png
  到最后,nginx之前的老进程全部关闭……
http://blog.51cto.com/attachment/201208/184947382.png
  这时,nginx.pid文件没有了
http://blog.51cto.com/attachment/201208/185018974.png
  到此,nginx.pid文件神奇消失的问题终于被找出来了。
  继续分析-----日志分割,依靠的是nginx.pid获取nginx的进程号,分割成功后,出现的情况是nginx依然昨天的日志,不写分割后的日志。
  那么现在需要对这个脚本进行修改,把stop函数中的-QUIT改为-TERM 立即关闭。(话说我这个脚本是来自官网改造的,看来官网也不是100%的准确哦,做运维要细心啊)
  官方脚本地址http://wiki.nginx.org/RedHatNginxInitScript
  再次运用此脚本重启
  


[*]service nginx restart
  

  问题不再重现,已经解决了。
  总结,一个小小的参数,可能会引发无限大的问题,所以,学知识要细心啊!
  =============================================================
  附录一:nginx的信号控制
  


[*]TERM,INT 快速关闭;
[*]QUIT      从容关闭
[*]HUP       平滑重启,重新加载配置文件;
[*]USER1   重新打开日志文件,在切割日志的时候用途较大;
[*]USER2   平滑升级可执行程序;
[*]WINCH   从容关闭工作进程;
  

  附录二:nginx的启动脚本如下
  


[*]#!/bin/sh
[*]#
[*]# nginx - this script starts and stops the nginx daemon
[*]#
[*]# chkconfig:   - 85 15
[*]# description:Nginx is an HTTP(S) server, HTTP(S) reverse \
[*]#               proxy and IMAP/POP3 proxy server
[*]# processname: nginx
[*]# config:      /etc/nginx/nginx.conf
[*]# config:      /etc/sysconfig/nginx
[*]# pidfile:   /var/run/nginx.pid
[*]
[*]# Source function library.
[*]#. /etc/rc.d/init.d/functions
[*]
[*]# Source networking configuration.
[*]#. /etc/sysconfig/network
[*]
[*]# Check that networking is up.
[*]green='\e[0;32m'
[*]red='\e[0;31m'
[*]NC='\e[0m'
[*]
[*]nginx="/usr/sbin/nginx"
[*]prog=$(basename $nginx)
[*]
[*]NGINX_CONF_FILE="/etc/nginx/nginx.conf"
[*]pidfile="/var/run/nginx.pid"
[*]lockfile=/var/lock/subsys/nginx
[*]
[*]make_dirs() {
[*]   # make required directories
[*]   user=`$nginx -V 2>&1 | grep "configure arguments:" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -`
[*]   if [ -z "`grep $user /etc/passwd`" ]; then
[*]       useradd -M -s /bin/nologin $user
[*]   fi
[*]   options=`$nginx -V 2>&1 | grep 'configure arguments:'`
[*]   for opt in $options; do
[*]       if [ `echo $opt | grep '.*-temp-path'` ]; then
[*]         value=`echo $opt | cut -d "=" -f 2`
[*]         if [ ! -d "$value" ]; then
[*]               # echo "creating" $value
[*]               mkdir -p $value && chown -R $user $value
[*]         fi
[*]       fi
[*]   done
[*]}
[*]
[*]start() {
[*]    [ -x $nginx ] || exit 5
[*]    [ -f $NGINX_CONF_FILE ] || exit 6
[*]    make_dirs
[*]    echo -e "Starting $prog ...................................\c"
[*]    $nginx -c $NGINX_CONF_FILE >/dev/null 2>&1
[*]    retval=$?
[*]   echo
[*]    [ $retval -eq 0 ] && touch $lockfile &&    echo -e "Started$prog ...................................[ ${green}OK${NC} ]"
[*]    [ $retval != 0 ]&& echo -e "Started$prog ................................[ ${red}Falied${NC} ]\r"
[*]   return $retval
[*]}
[*]
[*]stop() {
[*]    echo -e "Stopping $prog ...................................\c"
[*]    PID=`cat $pidfile`
[*]    killproc $prog -TERM
[*]    retval=$?
[*]    echo
[*]    [ $retval -eq 0 ] && rm -f $lockfile && echo -e "Stoped   $prog ...................................[ ${green}OK${NC} ]\r"
[*]    [ $retval != 0 ]&& echo -e "Stoped$prog ................................[ ${red}Falied${NC} ]\r"
[*]    return $retval
[*]}
[*]status(){
[*]    if [ -e $pidfile ]
[*]       then
[*]      PID=`cat $pidfile`
[*]      echo"Nginx (pid $PID) is running..."
[*]       else
[*]      echo"Nginx is stopped"
[*]    fi
[*]}
[*]
[*]restart() {
[*]    configtest || return $?
[*]    stop
[*]    sleep 1
[*]    start
[*]}
[*]
[*]reload() {
[*]    configtest || return $?
[*]    echo -n $"Reloading $prog: "
[*]    killproc $nginx -HUP
[*]    RETVAL=$?
[*]    echo
[*]}
[*]
[*]configtest() {
[*]$nginx -t -c $NGINX_CONF_FILE >/dev/null2>&1
[*]}
[*]
[*]case "$1" in
[*]    start)
[*]      $1
[*]      ;;
[*]    stop)
[*]      $1
[*]      ;;
[*]    status)
[*]      $1
[*]      ;;
[*]    restart)
[*]      $1
[*]      ;;
[*]    reload)
[*]      $1
[*]      ;;
[*]    configtest)
[*]      $1
[*]      ;;
[*]    *)
[*]      echo $"Usage: $0 {start|stop|status|restart|reload|configtest}"
[*]      exit 2
[*]esac
  

  附录三:日志切割脚本如下
  


[*]# cat /etc/logrotate.d/nginx
[*]/var/log/nginx/*.log {
[*]daily
[*]rotate 7
[*]missingok
[*]create 600 www www
[*]notifempty
[*]sharedscripts
[*]postrotate
[*]if [ -f /var/run/nginx.pid ]; then
[*]kill -USR1 $(cat /var/run/nginx.pid)
[*]fi
[*]endscript
[*]}
  



页: [1]
查看完整版本: 关于nginx信号控制的“故障”案例