Nginx

Nginx:執行 django 時出現 502 Bad Gateway 錯誤(111:連接被拒絕)到 uWSGI 套接字

  • October 4, 2019

我正在使用 Nginx、uWSGI、Django 和 Postgresql 堆棧建構應用程序。該應用程序使用 Nginx 和 uWSGI 之間的 Unix 套接字。套接字上的文件權限是 775。但我仍然得到這個權限錯誤:

[error] 6978#0: *6725 connect() to unix:/path/to/socket failed (111: Connection refused) while connecting to upstream, client: 54.250.253.225, server: example.com, request: "GET / HTTP/1.1", upstream: "uwsgi://unix:/path/to/socket:", host: "example.com"

Nginx 配置

# uWSGI upstream
upstream app{
   server  unix:/path/to/socket;
   }

# redirect www to non-www
server{
   listen  80;
   server_name www.example.com;
   return  301 http://example.com$request_uri;
}

# configuration of the server
server {
   # the port your site will be served on
   listen      80;
   # the domain name it will serve for

   # substitute your machine's IP address or FQDN
   server_name example.com
   charset     utf-8;

   # root folder
   root    /path/to/root;

   # max upload size
   client_max_body_size 20M;   # adjust to taste

   access_log  /path/to/access.log;
   error_log   /path/to/error.log;

   # Django media
   location /media  {
   # your Django project's media files - amend as required
   alias /path/to/media;  
   }

   location /static {
   # your Django project's static files - amend as required
   alias /path/to/static; 
   }

   # Finally, send all non-media requests to the Django server.
   location / {
       uwsgi_pass  app;
   # the uwsgi_params file you installed
   include     /path/to/uwsgi_params; 

   uwsgi_param Host $host;
   uwsgi_param X-Real-IP $remote_addr;
   uwsgi_param UWSGI_SCHEME $scheme;
   uwsgi_param SERVER_SOFTWARE nginx/nginx_version;
   }
}

我的虛擬環境中的文件都被 chown 到了 ubuntu:ubuntu。nginx使用者是ubuntu。

uWSGI 日誌

*** Starting uWSGI 2.0.12 (64bit) on [Sun Apr 17 17:24:37 2016] ***
compiled with version: 4.8.4 on 17 April 2016 14:40:25
os: Linux-3.13.0-85-generic #129-Ubuntu SMP Thu Mar 17 20:50:15 UTC 2016
nodename: ip-10-167-29-5
machine: x86_64
clock source: unix
pcre jit disabled
detected number of CPU cores: 1
current working directory: /path/to/app
detected binary path: /path/to/bin/uwsgi
chdir() to /path/to/chdir
your processes number limit is 30035
your memory page size is 4096 bytes
*** WARNING: you have enabled harakiri without post buffering. Slow upload could be rejected on post-unbuffered webservers *** 
detected max file descriptor number: 1024
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
uwsgi socket 0 bound to UNIX address /path/to/socket fd 3
Python version: 3.4.3 (default, Oct 14 2015, 20:31:36)  [GCC 4.8.4]
Set PythonHome to /path/to/home
Python main interpreter initialized at 0xa4df10
python threads support enabled
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 436608 bytes (426 KB) for 5 cores
*** Operational MODE: preforking ***
/path/to/lib/python3.4/site-packages/cloudinary/models.py:24: RemovedInDjango110Warning: SubfieldBase has been deprecated. Use Field.from_db_value instead.
 return meta(name, bases, d)

WSGI app 0 (mountpoint='') ready in 1 seconds on interpreter 0xa4df10 pid: 8567 (default app)
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI master process (pid: 8567)
spawned uWSGI worker 1 (pid: 8569, cores: 1)
spawned uWSGI worker 2 (pid: 8570, cores: 1)
spawned uWSGI worker 3 (pid: 8571, cores: 1)
spawned uWSGI worker 4 (pid: 8572, cores: 1)
spawned uWSGI worker 5 (pid: 8573, cores: 1)

有人可以告訴我是什麼導致了這個權限問題嗎?

我能夠自己解決問題。我重新啟動了伺服器。然後我重新啟動了 Nginx 和 uWSGI

sudo service nginx restart 
sudo service uwsgi restart

Nginx 重新啟動沒有問題。但是,uWSGI 返回了這個錯誤:

/etc/init.d/uwsgi: line 73: /usr/share/uwsgi/init/do_command: No such file or directory

我試圖切換到目錄。然而,它並不存在。因此,我在 uwsgi 目錄中創建了 init 目錄:

sudo mkdir init

然後我進入了新目錄:

cd init

在那個目錄中,我創建了 uWSGI 找不到的文件:do_command。

sudo nano do_command

打開文件編輯器後,我粘貼了我找到的這個文件:https ://raw.githubusercontent.com/jbq/uwsgi/master/debian/uwsgi-files/init/do_command :

# This is shell script, sourced by uWSGI init.d script

. /usr/share/uwsgi/init/snippets
. /usr/share/uwsgi/init/specific_daemon

do_command()
{
 local COMMAND="$1"
 shift

 local ERRORS=0

 # If command is given with arguments, i.e. 'start smth smth_else'
 if [ -n "$1" ]; then
   [ "x$VERBOSE" != "xno" ] && log_progress_msg "->"

   # Iterate over given configuration file specifications and:
   # * either print notice that conforming conffile wasn't found (if it
   #   wasn't)
   # * or execute given command with conforming conffile
   local CONFSPEC_PATH=""
   for CONFSPEC in "$@"; do
     CONFSPEC_RELPATH="$(relative_path_to_conffile_with_spec "$CONFSPEC")"
     if [ -z "${CONFSPEC_RELPATH}" ]; then
       log_progress_not_found "$CONFSPEC"
     else
       do_with_given_specific_daemon "$COMMAND" "$CONFSPEC_RELPATH"
       ERRORS="$(expr "$ERRORS" + "$?")"
     fi
   done

   [ "$ERRORS" -eq 0 ] && log_progress_done

   return "$ERRORS"
 fi

 # Do not start daemon if it was disabled.
 if [ "x$COMMAND" = "xstart" -a "x$RUN_AT_STARTUP" != "xyes" ]; then
   [ "x$VERBOSE" != "xno" ] && log_progress_msg "(disabled; see /etc/default/${NAME})"
   return 2
 fi

 local SOME_CONF_WAS_FOUND=no
 local UWSGI_APPS_CONFDIRS="$(ls -1d ${UWSGI_APPS_CONFDIR_GLOB})"

 # This construction is needed for supporting configuration file names with
 # spaces or control characters.
 #
 # See http://www.dwheeler.com/essays/filenames-in-shell.html (paragraph #4).
 #
 # Predefined delimeters are resetted to null character (by changing IFS and
 # setting -d option of 'read' command) and then:
 # * 'find -print0' command is used for finding all available confnames
 # * 'while ... read' loop is used for iterating over found confnames
 # 
 # Also process substitution is used, so that variables changed inside 'while'
 # loop will retain their values after exiting from loop.
 #
 # By default 'find' command use emacs-style regexps. Emacs-style regexp
 # processor with given regexp doesn't matches to file names with newline
 # character. Posix-style regexp processor is working good.
 #
 # With executing 'sed' over found paths, relative configuration file
 # paths are extracted from full paths provided with 'find' output.
 # Firstly, common directory path (UWSGI_CONFDIR) is stripped from 'find'
 # output. Secondly, all directories (except the first) and file extensions
 # are stripped from result of first substitution.
 #
 # For example: list of found paths
 # '/etc/uwsgi/apps-enabled/site.ini\0/etc/uwsgi/apps-enabled/dir/site2.ini'
 # is transformed by sed into 'apps-enabled/site\0apps-enabled/site2'.
 while IFS="" read -r -d "" RELATIVE_CONFPATH <&4 ; do
   if [ "x$SOME_CONF_WAS_FOUND" = "xno" -a "x$VERBOSE" != "xno" ]; then
     log_progress_msg "->"
   fi
   SOME_CONF_WAS_FOUND=yes
   do_with_given_specific_daemon "$COMMAND" "$RELATIVE_CONFPATH"
   ERRORS="$(expr "$ERRORS" + "$?")"
 done 4< <(find "$UWSGI_APPS_CONFDIRS" \
                 -regextype posix-basic \
                 -iregex ".*\.${UWSGI_CONFFILE_TYPES_REGEXP}\$" -a -xtype f \
                 -print0 \
           | sed -e "s:\(^\|\x0\)${UWSGI_CONFDIR}/:\1:g" \
                 -e "s:\([^\x0/]\+\)\([^\x0]\+\)\?/\([^/\x0]\+\)\.${UWSGI_CONFFILE_TYPES_REGEXP}\x0:\1/\3\x0:g" \
           | sort --zero-terminated --unique \
           )

 if [ "x$VERBOSE" != "xno" ]; then
   if [ "x$SOME_CONF_WAS_FOUND" = "xno" ]; then
     log_progress_msg "(omitted; missing conffile(s) in ${UWSGI_APPS_CONFDIR_GLOB})"
   elif [ "$ERRORS" -eq 0 ]; then
     log_progress_done
   fi
 fi

 return "$ERRORS"
}

do_with_given_specific_daemon()
{
 local COMMAND="$1"
 shift
 local RELATIVE_CONFPATH="$@"

 local ERRORS=0

 case "$COMMAND" in
   start)        do_start_specific_daemon "$RELATIVE_CONFPATH" ;;
   stop)         do_stop_specific_daemon "$RELATIVE_CONFPATH" ;;
   force-reload) do_force_reload_specific_daemon "$RELATIVE_CONFPATH" ;;
   reload|*)     do_reload_specific_daemon "$RELATIVE_CONFPATH" ;;
 esac
 case "$?" in
   0) log_progress_ok "$RELATIVE_CONFPATH" ;;
   1) log_progress_skip "$RELATIVE_CONFPATH" ;;
   *) log_progress_error "$RELATIVE_CONFPATH"
      ERRORS=1
   ;;
 esac

 return "$ERRORS"
}

# Print progress notification about successful command execution.
log_progress_ok()
{
 local RELATIVE_CONFPATH="$@"
 local CONFNAME=""

 [ "x$VERBOSE" = "xno" ] && return

 if [ "x$PRINT_CONFNAMES_IN_INITD_SCRIPT_OUTPUT" != "xno" ]; then
   CONFNAME="$(make_confname_for_progress_log "$RELATIVE_CONFPATH")"
   log_progress_msg "$CONFNAME"
 else
   log_progress_msg '.'
 fi
}

# Print progress notification about skipped command execution.
#
# It is printed, for example, when 'start' command was issued, but specific
# daemon is already started. Or when 'stop' command was issued, but specific
# daemon isn't runned yet.
log_progress_skip()
{
 local RELATIVE_CONFPATH="$@"
 local CONFNAME=""

 [ "x$VERBOSE" = "xno" ] && return

 if [ "x$PRINT_CONFNAMES_IN_INITD_SCRIPT_OUTPUT" != "xno" ]; then
   CONFNAME="$(make_confname_for_progress_log "$RELATIVE_CONFPATH")"
   log_progress_msg "(${CONFNAME})"
 else
   log_progress_msg "."
 fi
}

# Print progress notification about missing configuration file with given
# name.
log_progress_not_found()
{
 local RELATIVE_CONFPATH="$@"
 local CONFNAME=""

 [ "x$VERBOSE" = "xno" ] && return

 if [ "x$PRINT_CONFNAMES_IN_INITD_SCRIPT_OUTPUT" != "xno" ]; then
   CONFNAME="$(make_confname_for_progress_log "$RELATIVE_CONFPATH")"
 fi

 log_progress_msg "${CONFNAME}?"
}

# Print progress notification about failed command execution.
log_progress_error()
{
 local RELATIVE_CONFPATH="$@"
 local CONFNAME=""

 [ "x$VERBOSE" = "xno" ] && return

 if [ "x$PRINT_CONFNAMES_IN_INITD_SCRIPT_OUTPUT" != "xno" ]; then
   CONFNAME="$(make_confname_for_progress_log "$RELATIVE_CONFPATH")"
 fi

 log_progress_msg "${CONFNAME}!"
}

log_progress_done()
{
 log_progress_msg "done"
}

make_confname_for_progress_log()
{
 local RELATIVE_CONFPATH="$@"
 local CONFNAMESPACE="$(extract_confnamespace "$RELATIVE_CONFPATH")"
 local CONFNAME="$(extract_confname "$RELATIVE_CONFPATH")"

 echo "$(sanitize_confname "${CONFNAMESPACE}/${CONFNAME}")"
}

# Sanitize configuration file name for printing it in terminal.
sanitize_confname()
{
 local CONFNAME="$@"

 # In sanitizing:
 # * all control ASCII characters are replaced with '?' character
 # * confname with spaces is surrounded by single quotes.
 CONFNAME="$(echo -n "$CONFNAME" | tr '[\001-\037\177]' '?')"
 case "$CONFNAME" in
   *[[:space:]]*) echo "'$CONFNAME'" ;;
   *)             echo "$CONFNAME"   ;;
 esac
}

然後我重新啟動了 uWSGI:

sudo service uwsgi restart

Django 應用程序正常啟動。

看起來 uWSGI 服務正在偵聽具有不同絕對路徑的 Unix 套接字(由於chdir()呼叫)。您可以使用它lsof | grep "/path/to/socket"來查找正在偵聽的 Unix 套接字的絕對路徑。我想是的/path/to/chdir/path/to/socket

引用自:https://serverfault.com/questions/770985