Nginx 已停止且无法重新启动-open()“/run/nginx.pid”失败

Nginx 已停止且无法重新启动-open()“/run/nginx.pid”失败

我正在运行我的 django apis,部署在 Ubuntu 18、Nginx 上并通过 Supervisor 运行。

我使用 Certbot 进行 SSL 证书,这是此 Web 服务器上运行的唯一 Web 服务。这里未部署其他网站。

API 今天出现故障,nginx 停止工作。我无法重现发生这种情况的原因,必须手动重启。

我以前遇到过一次这种情况,并且在日志中有类似的错误消息。

以下是 nginx 错误日志。

2021/01/09 15:55:39 [crit] 9453#9453: *1331764 SSL_do_handshake() failed (SSL: error:1420918C:SSL routines:tls_early_post_process_client_hello:version too low) while SSL handshaking, client: <CLIENT IP ADDRESS>, server: 0.0.0.0:443
2021/01/09 20:39:55 [error] 9453#9453: *1337050 upstream prematurely closed connection while reading upstream, client: <CLIENT IP ADDRESS>, server: , request: "PUT /api/v1/APIURL/ HTTP/1.1", upstream: "http://127.0.0.1:8081/api/v1/APIURL", host: "<URL>", referrer: "<URL>"
2021/01/09 20:40:12 [error] 9453#9453: *1337057 upstream prematurely closed connection while reading upstream, client: <CLIENT IP ADDRESS>, server: , request: "PUT /api/v1/APIURL/ HTTP/1.1", upstream: "http://127.0.0.1:8081/api/v1/APIURL", host: "<URL>", referrer: "<URL>"
2021/01/09 20:41:02 [error] 9453#9453: *1337064 upstream prematurely closed connection while reading upstream, client:<CLIENT IP ADDRESS>, server: , request: "PUT /api/v1/URL/ HTTP/1.1", upstream: "http://127.0.0.1:8081/api/v1/URL/", host: "URL", referrer: "URL"
2021/01/10 03:51:29 [notice] 32527#32527: signal process started
2021/01/10 03:51:29 [error] 32527#32527: open() "/run/nginx.pid" failed (2: No such file or directory)
2021/01/10 03:51:34 [notice] 32533#32533: signal process started
2021/01/10 03:51:36 [notice] 32536#32536: signal process started
2021/01/10 03:51:38 [emerg] 32583#32583: bind() to 0.0.0.0:443 failed (98: Address already in use)
2021/01/10 03:51:38 [emerg] 32583#32583: bind() to 0.0.0.0:80 failed (98: Address already in use)
2021/01/10 03:51:38 [emerg] 32583#32583: bind() to 0.0.0.0:443 failed (98: Address already in use)
2021/01/10 03:51:38 [emerg] 32583#32583: bind() to 0.0.0.0:80 failed (98: Address already in use)
2021/01/10 03:51:38 [emerg] 32583#32583: bind() to 0.0.0.0:443 failed (98: Address already in use)
2021/01/10 03:51:38 [emerg] 32583#32583: bind() to 0.0.0.0:80 failed (98: Address already in use)
2021/01/10 03:51:38 [emerg] 32583#32583: bind() to 0.0.0.0:443 failed (98: Address already in use)
2021/01/10 03:51:38 [emerg] 32583#32583: bind() to 0.0.0.0:80 failed (98: Address already in use)
2021/01/10 03:51:38 [emerg] 32583#32583: bind() to 0.0.0.0:443 failed (98: Address already in use)
2021/01/10 03:51:38 [emerg] 32583#32583: bind() to 0.0.0.0:80 failed (98: Address already in use)
2021/01/10 03:51:38 [emerg] 32583#32583: still could not bind()
2021/01/10 03:51:40 [alert] 32534#32534: *6 open socket #10 left in connection 4
2021/01/10 03:51:40 [alert] 32534#32534: aborting
2021/01/10 03:51:40 [alert] 32529#32529: unlink() "/run/nginx.pid" failed (2: No such file or directory)

以下是我的 nginx、启动脚本和主管文件。

导师:

   [program:<PROGRAM NAME>]
    command = /home/ubuntu/start_scripts/script.sh
    directory = /home/ubuntu/LOCATION
    user = ubuntu
    stdout_logfile = /var/log/supervisor/api.log
    stderr_logfile = /var/log/supervisor/api_error.log
    redirect_stderr = true
    stopasgroup=true
    killasgroup=true

启动脚本:

#!/bin/bash

NAME="API"                                  # Name of the application
DJANGODIR=""           # Django project directory
SOCKFILE="<DJANGO APP>/run/gunicorn.sock"  # we will communicte using this unix socket
USER="ubuntu"                                      # the user to run as
GROUP="ubuntu"                                  # the group to run as
NUM_WORKERS="2"                                    # how many worker processes should Gunicorn spawn
TIMEOUT=180
DJANGO_SETTINGS_MODULE="config.settings.production"             # which settings file should Django use
DJANGO_WSGI_MODULE="config.wsgi"                   # WSGI module name
VIRTUAL_ENV_NAME="project-env"

echo "Starting $NAME as `whoami`"
export HOME="/home/ubuntu"
export WORKON_HOME=$HOME/.virtualenvs

# Activate the virtual environment
cd $DJANGODIR
source /usr/local/bin/virtualenvwrapper.sh
workon $VIRTUAL_ENV_NAME
export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE
#echo $PYTHONPATH
export PYTHONPATH=$DJANGODIR:$PYTHONPATH
#echo $PYTHONPATH
#export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3.4
export VIRTUALENVWRAPPER_PYTHON="/home/ubuntu/.virtualenvs/$VIRTUAL_ENV_NAME/bin/python"

# Create the run directory if it doesn't exist
RUNDIR=$(dirname $SOCKFILE)
test -d $RUNDIR || mkdir -p $RUNDIR

exec "/home/ubuntu/.virtualenvs/$VIRTUAL_ENV_NAME/bin/gunicorn" ${DJANGO_WSGI_MODULE}:application \
  --workers $NUM_WORKERS \
  --user=$USER --group=$GROUP \
  --bind="localhost":"8081" \
  --log-level="debug" \
  --timeout=$TIMEOUT

可用的 Ngnix 站点:

server {
    root <DJANGO PROJECT URL>;
    client_max_body_size 500M;
   
    
    location /healthcheck {
      return 200;
    }

    location /static/ {
      alias /home/ubuntu/apps/<DJANGO>/static/;
    }


    location / {
        proxy_pass http://localhost:8081;
        #proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Scheme $scheme;
        proxy_read_timeout 180s;
        proxy_connect_timeout 180s;
        proxy_set_header Connection '';
        proxy_http_version 1.1;
        chunked_transfer_encoding off;
        proxy_buffering off;
        proxy_cache off;
        proxy_redirect off;
        proxy_set_header Host $http_host;
    }


    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/<URL>/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/<URL>/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}
server {
    if ($host = <URL>) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    listen 80 default_server;
    server_name <URL-without-http>;
    return 404; # managed by Certbot

}

输出sudo netstat -nltup | grep -e 80 -e 443

tcp        0   0 127.0.0.1:8081   0.0.0.0:*       LISTEN      1079/python
tcp        0   0 0.0.0.0:443      0.0.0.0:*       LISTEN      -
tcp        0   0 0.0.0.0:80       0.0.0.0:*       LISTEN      -

请帮忙!

编辑:进一步检查日志后,我发现在日志关闭之前处理的最后一个请求如下。

"GET /.well-known/acme-challenge/G8e_pHx5B6fm9xuLzrjJmCvOnPbz8NhJFoWgt4dHGsg HTTP/1.1" 200 87 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)"

看起来好像是这个请求触发了 certbot 的某些操作,导致服务器启动失败。

相关内容