我正在运行我的 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 的某些操作,导致服务器启动失败。