使用 Supervisord 运行 2 个 Gunicorn 应用程序和 Nginx

use*_*464 3 python nginx supervisord gunicorn

无可否认,这个问题困扰了我好几个月。我只是拖延了修复其他错误并将其放在一边直到现在必须修复的地方-

我正在尝试运行 2 个单独的 gunicorn 应用程序并在同一个 supervisord.conf 文件中启动 nginx。当我启动supervisor时,我能够成功运行handlecalls应用程序,但是当我访问commentbox负责加载的网站时,我收到内部服务错误(500)。

当我使用命令字段后面的命令分别运行 handlecalls 和 commentbox 应用程序时,应用程序运行良好。当我尝试使用 supervisord 运行两者时,为什么评论框程序给我一个 500 错误?

我的主管脚本:

[program:nginx]
directory = /var/www/vmail
command = service nginx start -g "daemon off;"
autostart = True

[program:commentbox]
directory = /var/www/vmail
command = gunicorn app:app -bind 0.0.0.0:8000
autostart = True

[program:handlecalls]
directory = /var/www/vmail
command = gunicorn handle_calls:app --bind 0.0.0.0:8000
autostart = True

[supervisord]
directory = /var/www/vmail
logfile = /var/www/vmail/supervisorerrs.log
loglevel = trace
Run Code Online (Sandbox Code Playgroud)

Qua*_* To 5

这与supervisord无关。Supervisord 只是您启动/停止/重启服务器的一种方式。这更多地与您的服务器的配置有关。

基本原理:要使用 nginx 为两个 gunicorn 应用程序提供服务,您必须在两个不同的端口上运行它们,然后配置 nginx 以将请求 proxy_pass 到它们各自的端口。原因是:一旦一个进程在一个端口上运行,该端口就不能被另一个进程使用。

因此,将您的 supervisord 脚本中的配置更改为:

[program:commentbox]
directory = /var/www/vmail
command = gunicorn app:app --bind 0.0.0.0:8000
autostart = True

[program:handlecalls]
directory = /var/www/vmail
command = gunicorn handle_calls:app --bind 0.0.0.0:8001
autostart = True
Run Code Online (Sandbox Code Playgroud)

然后在你的 nginx 服务器的配置中 handlecalls

proxy_pass 127.0.0.1:8081
Run Code Online (Sandbox Code Playgroud)

更新:这是部署 Web 应用程序的基础知识

  1. 如上所述,一个端口只能被一个进程监听。
  2. 您可以将 nginx 用作 http 服务器,侦听端口80(或443用于 https),然后将请求传递给侦听其他端口的其他应用程序(例如,commentbox在 port 上8000和在 port上的handlecalls 8001
  3. 您可以通过添加某些服务器配置文件/etc/nginx/sites-available/(默认情况下。在某些情况下会有所不同)向 nginx 添加规则,以了解如何为您的应用程序提供服务。规则应该指定一种方式让 nginx 知道它应该将请求发送到哪个应用程序,例如:

    • 要重用相同的 http 端口 ( 80),应将每个应用程序分配到不同的域。即:commentbox.yourdomain.com为了commentboxhandlecalls.yourdomain.com为了handlecalls
    • 在同一个域上为两个不同的应用程序提供服务的方法是让它们在不同的端口上提供服务。例如:yourdomain.com将服务commentboxyourdomain.com:8080将服务handlecalls
    • 在同一个域和相同端口上为两个不同的应用程序提供服务的方法是让它们在两个不同的端点上提供服务。例如yourdomain.com/commentbox将成为commentboxyourdomain.com/handlecalls将成为handlecalls
  4. 将配置文件添加到 后/etc/nginx/sites-available/,您必须将这些文件符号链接到/etc/nginx/sites-enabled/,以便告诉 nginx 您要启用它们。您可以将文件直接添加到/etc/nginx/sites-enabled/,但我不建议这样做,因为它没有为您提供启用/禁用应用程序的便捷方法。

更新:以下是如何配置 nginx 以使用两个不同的子域为 gunicorn 应用程序提供服务:

  1. 添加两个子域commentbox.yourdomain.comhandlecalls.yourdomain.com,并将它们都指向您服务器的 IP。
  2. commentboxat创建一个配置文件,/etc/nginx/sites-available/commentbox内容如下(根据需要编辑):

    server {
        listen 80; 
    
        server_name           commentbox.yourdomain.com;
    
        root                  /path/to/your/application/static/folder;    
        location / {
            try_files         $uri @app;
        }
    
        location @app {
            proxy_set_header   Host $http_host;
            proxy_set_header   X-Real-IP $remote_addr;
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
    
            proxy_redirect     off;
            proxy_pass         http://127.0.0.1:8000;
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 使用以下内容为handlecallsat创建配置文件/etc/nginx/sites-available/handlecalls(根据需要进行编辑):

    server {
        listen 80; 
    
        server_name           handlecalls.yourdomain.com;
    
        root                  /path/to/your/application/static/folder;    
        location / {
            try_files         $uri @app;
        }
    
        location @app {
            proxy_set_header   Host $http_host;
            proxy_set_header   X-Real-IP $remote_addr;
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
    
            proxy_redirect     off;
            proxy_pass         http://127.0.0.1:8001;
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  4. 创建符号链接以启用这些服务器:

    sudo ln -s /etc/nginx/sites-available/commentbox /etc/nginx/sites-enabled/
    sudo ln -s /etc/nginx/sites-available/handlecalls /etc/nginx/sites-enabled/
    
    Run Code Online (Sandbox Code Playgroud)
  5. 重启nginx生效

    sudo service nginx restart
    
    Run Code Online (Sandbox Code Playgroud)