FastCGI — Flask 文档

来自菜鸟教程
Flask/docs/1.1.x/deploying/fastcgi
跳转至:导航、​搜索

快速CGI

FastCGI 是 nginxlighttpdcherokee 等服务器上的部署选项; 有关其他选项,请参阅 uWSGIStandalone WSGI Containers。 要将您的 WSGI 应用程序与其中任何一个一起使用,您首先需要一个 FastCGI 服务器。 最受欢迎的是 flup,我们将在本指南中使用它。 确保安装它以进行后续操作。

当心

请提前确保您的应用程序文件中的任何 app.run() 调用都在 if __name__ == '__main__': 块内或移动到单独的文件中。 只要确保它没有被调用,因为如果我们将该应用程序部署到 FastCGI,这将始终启动我们不想要的本地 WSGI 服务器。


创建 .fcgi 文件

首先,您需要创建 FastCGI 服务器文件。 我们称之为 yourapplication.fcgi:

#!/usr/bin/python
from flup.server.fcgi import WSGIServer
from yourapplication import app

if __name__ == '__main__':
    WSGIServer(app).run()

这足以让 Apache 工作,但是 nginx 和旧版本的 lighttpd 需要显式传递套接字以与 FastCGI 服务器通信。 为此,您需要将套接字的路径传递给 WSGIServer

WSGIServer(application, bindAddress='/path/to/fcgi.sock').run()

该路径必须与您在服务器配置中定义的路径完全相同。

yourapplication.fcgi 文件保存在您会再次找到的地方。 在 /var/www/yourapplication 或类似的东西中使用它是有意义的。

确保在该文件上设置可执行位,以便服务器可以执行它:

$ chmod +x /var/www/yourapplication/yourapplication.fcgi

配置 Apache

上面的示例对于基本的 Apache 部署来说已经足够了,但是您的 .fcgi 文件将出现在您的应用程序 URL 中,例如 example.com/yourapplication.fcgi/news/。 有几种方法可以配置您的应用程序,以使 yourapplication.fcgi 不会出现在 URL 中。 更好的方法是使用 ScriptAlias 和 SetHandler 配置指令将请求路由到 FastCGI 服务器。 以下示例使用 FastCgiServer 启动应用程序的 5 个实例,这些实例将处理所有传入请求:

LoadModule fastcgi_module /usr/lib64/httpd/modules/mod_fastcgi.so

FastCgiServer /var/www/html/yourapplication/app.fcgi -idle-timeout 300 -processes 5

<VirtualHost *>
    ServerName webapp1.mydomain.com
    DocumentRoot /var/www/html/yourapplication

    AddHandler fastcgi-script fcgi
    ScriptAlias / /var/www/html/yourapplication/app.fcgi/

    <Location />
        SetHandler fastcgi-script
    </Location>
</VirtualHost>

这些进程将由 Apache 管理。 如果您使用独立的 FastCGI 服务器,则可以改用 FastCgiExternalServer 指令。 请注意,以下路径不是真实的,它只是用作其他指令(例如 AliasMatch)的标识符:

FastCgiServer /var/www/html/yourapplication -host 127.0.0.1:3000

如果您无法设置 ScriptAlias,例如在共享 Web 主机上,您可以使用 WSGI 中间件从 URL 中删除 yourapplication.fcgi。 设置.htaccess:

<IfModule mod_fcgid.c>
   AddHandler fcgid-script .fcgi
   <Files ~ (\.fcgi)>
       SetHandler fcgid-script
       Options +FollowSymLinks +ExecCGI
   </Files>
</IfModule>

<IfModule mod_rewrite.c>
   Options +FollowSymlinks
   RewriteEngine On
   RewriteBase /
   RewriteCond %{REQUEST_FILENAME} !-f
   RewriteRule ^(.*)$ yourapplication.fcgi/$1 [QSA,L]
</IfModule>

设置你的application.fcgi:

#!/usr/bin/python
#: optional path to your local python site-packages folder
import sys
sys.path.insert(0, '<your_local_path>/lib/python<your_python_version>/site-packages')

from flup.server.fcgi import WSGIServer
from yourapplication import app

class ScriptNameStripper(object):
   def __init__(self, app):
       self.app = app

   def __call__(self, environ, start_response):
       environ['SCRIPT_NAME'] = ''
       return self.app(environ, start_response)

app = ScriptNameStripper(app)

if __name__ == '__main__':
    WSGIServer(app).run()

配置 lighttpd

lighttpd 的基本 FastCGI 配置如下所示:

fastcgi.server = ("/yourapplication.fcgi" =>
    ((
        "socket" => "/tmp/yourapplication-fcgi.sock",
        "bin-path" => "/var/www/yourapplication/yourapplication.fcgi",
        "check-local" => "disable",
        "max-procs" => 1
    ))
)

alias.url = (
    "/static/" => "/path/to/your/static/"
)

url.rewrite-once = (
    "^(/static($|/.*))$" => "$1",
    "^(/.*)$" => "/yourapplication.fcgi$1"
)

请记住启用 FastCGI、别名和重写模块。 此配置将应用程序绑定到 /yourapplication。 如果您希望应用程序在 URL 根目录中工作,您必须使用 LighttpdCGIRootFix 中间件解决 lighttpd 错误。

确保仅在将应用程序安装到 URL 根目录时才应用它。 此外,有关 FastCGI 和 Python 的更多信息,请参阅 Lighty 文档(请注意,不再需要显式地将套接字传递给 run())。


配置nginx

在 nginx 上安装 FastCGI 应用程序有点不同,因为默认情况下不转发 FastCGI 参数。

nginx 的基本 Flask FastCGI 配置如下所示:

location = /yourapplication { rewrite ^ /yourapplication/ last; }
location /yourapplication { try_files $uri @yourapplication; }
location @yourapplication {
    include fastcgi_params;
    fastcgi_split_path_info ^(/yourapplication)(.*)$;
    fastcgi_param PATH_INFO $fastcgi_path_info;
    fastcgi_param SCRIPT_NAME $fastcgi_script_name;
    fastcgi_pass unix:/tmp/yourapplication-fcgi.sock;
}

此配置将应用程序绑定到 /yourapplication。 如果你想把它放在 URL 根目录中,它会更简单一些,因为你不必弄清楚如何计算 PATH_INFOSCRIPT_NAME

location / { try_files $uri @yourapplication; }
location @yourapplication {
    include fastcgi_params;
    fastcgi_param PATH_INFO $fastcgi_script_name;
    fastcgi_param SCRIPT_NAME "";
    fastcgi_pass unix:/tmp/yourapplication-fcgi.sock;
}

运行 FastCGI 进程

由于 nginx 等不加载 FastCGI 应用程序,因此您必须自己完成。 Supervisor 可以管理 FastCGI 进程。 您可以四处寻找其他 FastCGI 进程管理器或编写脚本以在启动时运行您的 .fcgi 文件,例如 使用 SysV init.d 脚本。 对于临时解决方案,您始终可以在 GNU 屏幕中运行 .fcgi 脚本。 有关详细信息,请参阅 man screen,并注意这是一个手动解决方案,不会在系统重启后持续:

$ screen
$ /var/www/yourapplication/yourapplication.fcgi

调试

FastCGI 部署往往难以在大多数 Web 服务器上调试。 通常,服务器日志告诉您的唯一内容是“标题过早结束”。 为了调试应用程序,唯一可以真正让您了解它为什么会中断的方法是切换到正确的用户并手动执行应用程序。

此示例假设您的应用程序名为 application.fcgi,并且您的 Web 服务器用户是 www-data:

$ su www-data
$ cd /var/www/yourapplication
$ python application.fcgi
Traceback (most recent call last):
  File "yourapplication.fcgi", line 4, in <module>
ImportError: No module named yourapplication

在这种情况下,错误似乎是“您的应用程序”不在 python 路径上。 常见问题有:

  • 正在使用的相对路径。 不要依赖当前的工作目录。
  • 代码取决于未由 Web 服务器设置的环境变量。
  • 使用了不同的 python 解释器。