Nginx 使用“service nginx start”挂起

T0M*_*FeR 12 ubuntu nginx service systemctl docker

我已经为我的生产服务器编译了带有自定义路径的 nginx,当我尝试使用以下命令启动/重新启动服务时:

service nginx start
Run Code Online (Sandbox Code Playgroud)

或者

service nginx restart
Run Code Online (Sandbox Code Playgroud)

它进入一个新行而不返回shell: 运行命令时的终端图片

所以问题是我无法使用service命令控制nginx 。该服务实际上在运行,但它不会向我返回一个 shell,所以我总是必须按ctrl+c才能将其取回。

我还必须提到 nginx 在通过自己的nginx命令调用它时运行得很好,并且使用nginx -s stop/reload.

这个问题在使用systemctl start nginx中仍然存在,但systemctl stop nginx工作得很好。

信息:

$ lsb_release -a
    Distributor ID: Ubuntu
    Description:    Ubuntu 15.10
    Release:    15.10
    Codename:   wily

$ uname -r
    4.2.0-27-generic

$ nginx -V
    nginx version: nginx/1.9.11
    built by gcc 5.2.1 20151010 (Ubuntu 5.2.1-22ubuntu2) 
    built with OpenSSL 1.0.2d 9 Jul 2015
    TLS SNI support enabled
    configure arguments: --sbin-path=/usr/bin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --with-debug --with-pcre --with-http_ssl_module

$ cat /etc/default/nginx
    NGINX_CONF_FILE=/etc/nginx/nginx.conf
    DAEMON=/usr/bin/nginx

$ cat /etc/init.d/nginx
    NGINX_BIN=/usr/bin/nginx
    test -x $NGINX_BIN || { echo "$NGINX_BIN not installed"; 
        if [ "$1" = "stop" ]; then exit 0;
        else exit 5; fi; }
    NGINX_PID=/var/run/nginx.pid

    # Check for existence of needed config file and read it
    #NGINX_CONFIG=/etc/sysconfig/nginx
    #test -r $NGINX_CONFIG || { echo "$NGINX_CONFIG not existing";
    #   if [ "$1" = "stop" ]; then exit 0;
    #   else exit 6; fi; }
    #
    # Read config   
    #. $NGINX_CONFIG

    # Source LSB init functions
    # providing start_daemon, killproc, pidofproc, 
    # log_success_msg, log_failure_msg and log_warning_msg.
    # This is currently not used by UnitedLinux based distributions and
    # not needed for init scripts for UnitedLinux only. If it is used,
    # the functions from rc.status should not be sourced or used.
    #. /lib/lsb/init-functions

    # Shell functions sourced from /etc/rc.status:
    #      rc_check         check and set local and overall rc status
    #      rc_status        check and set local and overall rc status
    #      rc_status -v     be verbose in local rc status and clear it afterwards
    #      rc_status -v -r  ditto and clear both the local and overall rc status
    #      rc_status -s     display "skipped" and exit with status 3
    #      rc_status -u     display "unused" and exit with status 3
    #      rc_failed        set local and overall rc status to failed
    #      rc_failed <num>  set local and overall rc status to <num>
    #      rc_reset         clear both the local and overall rc status
    #      rc_exit          exit appropriate to overall rc status
    #      rc_active        checks whether a service is activated by symlinks
    . /etc/rc.status

    # Reset status of this service
    rc_reset

    # Return values acc. to LSB for all commands but status:
    # 0   - success
    # 1       - generic or unspecified error
    # 2       - invalid or excess argument(s)
    # 3       - unimplemented feature (e.g. "reload")
    # 4       - user had insufficient privileges
    # 5       - program is not installed
    # 6       - program is not configured
    # 7       - program is not running
    # 8--199  - reserved (8--99 LSB, 100--149 distrib, 150--199 appl)
    # 
    # Note that starting an already running service, stopping
    # or restarting a not-running service as well as the restart
    # with force-reload (in case signaling is not supported) are
    # considered a success.

    case "$1" in
        start)
        echo -n "Starting nginx "
        ## Start daemon with startproc(8). If this fails
        ## the return value is set appropriately by startproc.
        /sbin/startproc -p $NGINX_PID $NGINX_BIN

        # Remember status and be verbose
        rc_status -v
        ;;
        stop)
        echo -n "Shutting down nginx "
        ## Stop daemon with killproc(8) and if this fails
        ## killproc sets the return value according to LSB.

        /sbin/killproc -p $NGINX_PID -TERM $NGINX_BIN

        # Remember status and be verbose
        rc_status -v
        ;;
        try-restart|condrestart)
        ## Do a restart only if the service was active before.
        ## Note: try-restart is now part of LSB (as of 1.9).
        ## RH has a similar command named condrestart.
        if test "$1" = "condrestart"; then
            echo "${attn} Use try-restart ${done}(LSB)${attn} rather than condrestart ${warn}(RH)${norm}"
        fi
        $0 status
        if test $? = 0; then
            $0 restart
        else
            rc_reset    # Not running is not a failure.
        fi
        # Remember status and be quiet
        rc_status
        ;;
        restart)
        ## Stop the service and regardless of whether it was
        ## running or not, start it again.
        $0 stop
        $0 start

        # Remember status and be quiet
        rc_status
        ;;
        force-reload)
        ## Signal the daemon to reload its config. Most daemons
        ## do this on signal 1 (SIGHUP).
        ## If it does not support it, restart the service if it
        ## is running.

        echo -n "Reload service nginx "
        ## if it supports it:
        /sbin/killproc -p $NGINX_PID -HUP $NGINX_BIN
        #touch /run/nginx.pid
        rc_status -v

        ## Otherwise:
        #$0 try-restart
        #rc_status
        ;;
        reload)
        ## Like force-reload, but if daemon does not support
        ## signaling, do nothing (!)

        # If it supports signaling:
        echo -n "Reload service nginx "
        /sbin/killproc -p $NGINX_PID -HUP $NGINX_BIN
        #touch /run/nginx.pid
        rc_status -v

        ## Otherwise if it does not support reload:
        #rc_failed 3
        #rc_status -v
        ;;
        reopen)
            echo -n "Reopen the logfiles "
            /sbin/killproc -p $NGINX_PID -USR1 $NGINX_BIN
            rc_status -v
            ;;

        status)
        echo -n "Checking for service nginx "
        ## Check status with checkproc(8), if process is running
        ## checkproc will return with exit status 0.

        # Return value is slightly different for the status command:
        # 0 - service up and running
        # 1 - service dead, but /run/  pid  file exists
        # 2 - service dead, but /var/lock/ lock file exists
        # 3 - service not running (unused)
        # 4 - service status unknown :-(
        # 5--199 reserved (5--99 LSB, 100--149 distro, 150--199 appl.)

        # NOTE: checkproc returns LSB compliant status values.
        /sbin/checkproc -p $NGINX_PID $NGINX_BIN
        # NOTE: rc_status knows that we called this init script with
        # "status" option and adapts its messages accordingly.
        rc_status -v
        ;;
        probe)
        ## Optional: Probe for the necessity of a reload, print out the
        ## argument to this init script which is required for a reload.
        ## Note: probe is not (yet) part of LSB (as of 1.9)

        test /etc/nginx/nginx.conf -nt /run/nginx.pid && echo reload
        ;;
        *)
        echo "Usage: $0 {start|stop|status|try-restart|restart|force-reload|reload|probe}"
        exit 1
        ;;
    esac
    rc_exit
Run Code Online (Sandbox Code Playgroud)

更新:在 CoreOS alpha 上使用 Docker 容器时,问题仍然存在。

更新2:下面是输出用于strace -o log -f service nginx startjournalctl -xe

strace -o log -f service nginx start 日志输出 [太长,无法在此处发布]


    journalctl -xe
    Feb 26 07:25:38 lucifer polkitd(authority=local)[870]: Registered Authentication Agent for unix-process:8181:8813595 (system bus name :1.77 [/usr/bin/pkttyagent --notify-fd 5 --fallback], o
Feb 26 07:25:38 lucifer systemd[1]: Starting The NGINX HTTP and reverse proxy server...
-- Subject: Unit nginx.service has begun start-up
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
-- 
-- Unit nginx.service has begun starting up.
Feb 26 07:25:38 lucifer nginx[8211]: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
Feb 26 07:25:38 lucifer nginx[8211]: nginx: configuration file /etc/nginx/nginx.conf test is successful
Feb 26 07:25:38 lucifer systemd[1]: nginx.service: PID file /var/run/nginx.pid not readable (yet?) after start: No such file or directory
Feb 26 07:25:43 lucifer polkitd(authority=local)[870]: Unregistered Authentication Agent for unix-process:8181:8813595 (system bus name :1.77, object path /org/freedesktop/PolicyKit1/Authen
Run Code Online (Sandbox Code Playgroud)

小智 9

我在 Ubuntu 16.04、systemd 和 NginX 1.10.1 中遇到了同样的问题。

我使用的是默认nginx.service文件:https : //www.nginx.com/resources/wiki/start/topics/examples/systemd/

问题是nginx.pid位置。为了解决它,我:

  1. 在没有服务的情况下启动 Nginx

    sudo nginx start
    
    Run Code Online (Sandbox Code Playgroud)
  2. 更新了定位数据库

    sudo updatedb
    
    Run Code Online (Sandbox Code Playgroud)
  3. 找到pid文件的位置

    locate "nginx.pid"
    
    Run Code Online (Sandbox Code Playgroud)
  4. 将 nginx.service 文件更新到我找到它的位置

    PIDFile=/usr/local/nginx/logs/nginx.pid
    
    Run Code Online (Sandbox Code Playgroud)

    (不知道为什么它存储在我的日志目录中......)

  5. 然后运行 ​​daemon-reload 重新加载nginx.service文件

    systemctl daemon-reload
    
    Run Code Online (Sandbox Code Playgroud)

之后,systemctl start nginx就像一个魅力。希望这可以帮助。


Die*_*goG 4

它因以下错误而挂起:

PID file /var/run/nginx.pid not readable (yet?) after start
Run Code Online (Sandbox Code Playgroud)

较新的 Linux 发行版附带了systemd。如果您使用与发行版捆绑在一起的服务,您将获得已针对 systemd 配置的服务。

由于您正在从源代码编译 nginx 并且使用 SysV 初始化文件 ( /etc/init.d/nginx ),systemd 将使用生成器来解析它 ( systemd-sysv-generator )。

在 SysV 脚本中,定义 pid 文件并使用以下命令启动进程:

NGINX_PID=/var/run/nginx.pid
...
/sbin/startproc -p $NGINX_PID $NGINX_BIN
Run Code Online (Sandbox Code Playgroud)

如果我没记错的话,您在 Ubuntu 上使用 SUSE Linux 初始化脚本(因为startproc命令),该 startproc 命令仅读取 pid 文件(由-p参数指定),它不会创建它,因此 systemd找不到 pid 文件并且挂起。

对于您的情况,解决方案是在 SysV 初始化脚本中创建 pid 文件(位于/var/run/nginx.pid位置)、使用 Ubuntu SysV 初始化脚本或 systemd 脚本。

当您有正确的 SysV init 脚本来创建 pid 文件时,也可能会发生这种情况(不是您所发生的情况),但它与文件顶部注释的不同。systemd 生成器会读取注释,例如:

# pidfile: /var/run/nginxd.pid
Run Code Online (Sandbox Code Playgroud)

并使用那里定义的pidfile。

更多信息: