如何在Ubuntu16.04上使用Gunicorn和Nginx部署FalconWeb应用程序

来自菜鸟教程
跳转至:导航、​搜索

介绍

Falcon 是一个用于构建 Web 应用程序的最小 Python 框架。 它非常适合构建遵循 REST 架构风格的 API。 它是一个低级、高性能的框架,它试图在不牺牲开发速度的情况下做尽可能少的事情。

在本教程中,您将构建和部署 Falcon Web 应用程序。 Falcon 是一个 WSGI 框架,因此您将安装和使用 Gunicorn,一个 WSGI 应用程序服务器,为应用程序提供服务。 然后,您将创建一个使用 Nginx 作为反向代理服务器的生产就绪环境,以在传入请求到达 Gunicorn 之前对其进行处理。

先决条件

要完成本教程,您需要:

第 1 步——创建 Python 虚拟环境

在我们开始编写代码或设置服务之前,我们将在服务器上为我们的应用程序创建一个 Python 虚拟环境。

以非 root 用户身份连接到您的服务器:

ssh sammy@your_server_ip

Falcon 适用于 Python 2.x 和 Python 3.x,但我们将使用 Ubuntu 16.04 中可用的最新 Python 版本,即 Python 3.5。

我们将使用 pipvirtualenv 来设置我们的 Falcon 应用程序。 要了解有关这些工具的更多信息,请阅读我们关于 常用 Python 工具 的教程。

首先,安装 virtualenv:

sudo apt-get install virtualenv

接下来,创建一个存放应用程序源代码和虚拟环境的目录,然后切换到该目录:

mkdir falcon_app
cd falcon_app

然后创建虚拟环境:

virtualenv venv -p /usr/bin/python3

此命令在目录 venv 内创建一个虚拟环境。 -p 标志指定虚拟环境中使用的 Python 版本。

你会看到这个输出:

OutputAlready using interpreter /usr/bin/python3
Using base prefix '/usr'
New python executable in /home/sammy/falcon_app/venv/bin/python3
Also creating executable in /home/sammy/falcon_app/venv/bin/python
Installing setuptools, pkg_resources, pip, wheel...done.

现在激活虚拟环境:

. venv/bin/activate

要切换回系统范围的 Python 解释器,请通过发出以下命令停用虚拟环境:

deactivate

现在您已经设置了 Python 虚拟环境,让我们安装所需的 Python 包。

第 2 步 — 使用 pip 安装 Falcon 和 Gunicorn

我们需要安装 falcon 包,因为我们使用 Gunicorn 来服务我们的应用程序,所以我们也需要安装它。 这两个都可以通过 pip 获得,

您可以通过以下两种方式之一安装 Falcon。 Falcon 有一个可以用 pip install falcon 安装的二进制文件,但是当用 Cython 编译时,Falcon 可以获得额外的速度提升。 发出以下命令来安装 Cython,然后通知 Falcon 检测它并使用系统的 C 编译器自行编译:

sudo apt-get install build-essential python3-dev
pip install cython
pip install --no-binary :all: falcon

接下来,安装 Gunicorn:

pip install gunicorn

让我们继续编写我们简单的 Falcon 应用程序。

第 3 步 — 使用 Falcon 编写简单的 Web 应用程序

让我们创建一个简单的单文件 Falcon 应用程序。 在falcon_app目录下创建文件main.py

nano main.py

使用以下内容填充文件,这将创建一个 Falcon 应用程序,当人们访问 /test 路由时,该应用程序会显示一条简单的测试消息:

主文件

import falcon

class TestResource(object):
    def on_get(self, req, res):
        """Handles all GET requests."""
        res.status = falcon.HTTP_200  # This is the default status
        res.body = ('This is me, Falcon, serving a resource!')

# Create the Falcon application object
app = falcon.API()

# Instantiate the TestResource class
test_resource = TestResource()

# Add a route to serve the resource
app.add_route('/test', test_resource)

在这个文件中,我们创建了一个名为 TestResource 的类。 此类包含定义我们要发送的响应的 on_get 方法。 然后我们创建 Falcon API 和 TestResource 的实例。 然后我们将路由 /test 添加到 API 并将资源对象 test_resource 附加到它。

每当 GET 请求发送到 /test URL 时,就会调用 TestResourceon_get() 方法。 响应状态和正文分别使用变量 res.statusres.body 设置。

保存文件并关闭编辑器。 让我们测试应用程序。

第 4 步 — 使用 Gunicorn 为 Falcon 应用程序提供服务

在我们完成使用 Nginx 使我们的应用程序生产就绪的工作之前,让我们通过使用 Gunicorn 来确保我们的应用程序能够正常工作。

确保您位于 falcon_app 目录中。 使用以下命令启动 Gunicorn:

gunicorn -b 0.0.0.0:5000 main:app --reload

这将启动 Gunicorn 并在端口 5000 上的 0.0.0.0 处为我们的 Web 应用程序提供服务,从其输出中可以看出:

Output[2016-11-14 16:33:41 +0000] [9428] [INFO] Starting gunicorn 19.6.0
[2016-11-14 16:33:41 +0000] [9428] [INFO] Listening at: http://0.0.0.0:5000 (9428)
[2016-11-14 16:33:41 +0000] [9428] [INFO] Using worker: sync
[2016-11-14 16:33:41 +0000] [9431] [INFO] Booting worker with pid: 9431

您可以使用任何您喜欢的端口号,但请确保它高于 1024 并且没有被任何其他程序使用。

main:app 选项告诉 Gunicorn 调用文件 main.py 中可用的应用程序对象 app

Gunicorn 提供了一个可选的 --reload 开关,它告诉 Gunicorn 即时检测任何代码更改。 这样您就可以更改代码而无需重新启动 Gunicorn。

通过在本地计算机上打开 Web 浏览器并在浏览器中访问 http://your_server_ip:5000/test 来测试您的应用程序。 您将看到 Web 应用程序的以下输出:

CTRL+C 停止 Gunicorn。 让我们以更适合生产的方式进行设置。

第 5 步 — 使用 Nginx 将请求代理到 Gunicorn

我们将设置和配置 Nginx 以将所有 Web 请求代理到 Gunicorn,而不是让 Gunicorn 直接服务来自外部世界的请求。 通过这样做,您的 Web 应用程序的所有请求首先由 Nginx 遇到,然后路由到应用程序服务器。

首先,通过执行以下命令安装 Nginx:

sudo apt-get install nginx

接下来,在 /etc/nginx/sites-available 目录下新建一个名为 falcon_app.conf 的配置文件。 此文件将配置 Nginx 以将所有来自您服务器 IP 地址的请求代理到我们 Falcon 应用程序的 Gunicorn 服务器。

sudo nano /etc/nginx/sites-available/falcon_app.conf

将以下内容添加到文件中:

/etc/nginx/sites-available/falcon_app.conf

server {
    listen 80;
    server_name your_server_ip_or_domain;

    location / {
        include proxy_params;
        proxy_pass http://localhost:5000;
    }
}

此配置告诉 Nginx 监听端口 80 并将所有 HTTP 请求代理到 http://localhost:5000,这是 Gunicorn 将监听的地方。

通过在 /etc/nginx/sites-enabled 目录中创建指向此文件的符号链接来激活此配置:

sudo ln -s /etc/nginx/sites-available/falcon_app.conf /etc/nginx/sites-enabled/falcon_app.conf

然后通过从 /etc/nginx/sites-enabled 目录中删除其符号链接来禁用默认 Nginx 配置文件:

sudo rm /etc/nginx/sites-enabled/default

确保任何 Nginx 文件中都没有语法错误:

sudo nginx -t

如果您有有效的配置,您将看到此消息:

Outputnginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

如果您发现任何错误,请修复它们并再次测试。

重启 Nginx 使新配置生效。

sudo systemctl restart nginx

现在再次启动 Gunicorn,但将监听地址从 0.0.0.0 更改为 localhost 以防止公共访问 Gunicorn:

gunicorn -b localhost:5000 main:app --reload

如果您已启用,则允许通过服务器的防火墙访问端口 80

sudo ufw allow 80

注意:如果您使用 https 为您的 Web 应用程序提供服务,请确保使用 ufw 允许端口 443。 另外,请务必阅读我们关于 如何使用 Let's Encrypt 保护 Nginx 的文章。


最后,通过访问 http://your_server_ip/test 测试应用程序,您将看到与之前看到的相同的输出。

请注意,您不再需要 URL 中的端口号,因为您的请求现在通过 Nginx,它在默认 HTTP 端口 80 上运行。 您将在浏览器中看到以下输出:

CTRL+C 停止应用服务器。 让我们将我们的 Falcon 应用程序配置为像我们的其他服务一样在后台自动启动。

第 7 步 — 使用 Systemd 管理 Gunicorn

我们应该确保我们的应用程序在每次服务器启动时自动启动,就像 Nginx 一样。 如果我们的服务器意外重启或因任何原因不得不重启,我们不应该手动启动 Gunicorn。

为了配置它,我们将为我们的 Gunicorn 应用程序创建一个 Systemd 单元文件,以便我们可以管理它。

首先,我们在 /etc/systemd/system 目录中为我们的应用程序创建一个文件,扩展名为 .service

sudo nano /etc/systemd/system/falcon_app.service

单元文件由部分组成。 [Unit] 部分用于指定我们服务的元数据和依赖项,包括对我们服务的描述以及何时启动我们的服务。

将此配置添加到文件中:

/etc/systemd/system/falcon_app.service

[Unit]
Description=Gunicorn instance to serve the falcon application
After=network.target

我们指定服务应该在 达到网络目标后启动 。 换句话说,我们只有在网络服务准备好之后才启动这个服务。

[Unit] 部分之后,我们定义 [Service] 部分,我们在其中指定如何启动服务。 将此添加到配置文件中:

/etc/systemd/system/falcon_app.service

[Service]
User=sammy
Group=www-data
PIDFile=/tmp/gunicorn.pid
Environment="PATH=/home/sammy/falcon_app/venv/bin"
WorkingDirectory=/home/sammy/falcon_app
ExecStart=/home/sammy/falcon_app/venv/bin/gunicorn --workers 3 -b localhost:5000 main:app
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID

我们首先定义运行服务的用户和组。 然后我们定义一个文件来存储服务的PID(进程ID); 此 PID 用于停止或重新加载服务。

此外,我们指定 Python 虚拟环境,即应用程序的工作目录。 以及启动应用程序要执行的命令。 我们将启动 Gunicorn 的命令分配给 ExecStart 变量。 --workers 标志用于定义 Gunicorn 应该开始的工人数量。 Gunicorn 文档建议您将工作人员的数量设置为 2n+1,其中 n 是 CPU 内核的数量。 假设您的服务器有一个 CPU 内核,我们得到数字 3

ExecReloadExecStop 变量定义了服务应该如何启动和停止。

最后,我们添加 [Install] 部分,如下所示:

/etc/systemd/system/falcon_app.service

[Install]
WantedBy=multi-user.target

Install 部分允许您启用和禁用该服务。 WantedBy 指令在 /etc/systemd/system 内创建一个名为 multi-user.target 的目录,并且将在那里创建该文件的符号链接。 禁用此服务将从目录中删除此文件。

保存文件,关闭编辑器,然后启动新服务:

sudo systemctl start falcon_app

然后启用此服务,以便每次服务器启动时,Gunicorn 都会开始为 Web 应用程序提供服务:

sudo systemctl enable falcon_app

再次将浏览器指向 http://your_server_ip/test 以查看您的应用程序。 Nginx 和 Gunicorn 都在后台运行。 如果您需要更新您的 Falcon 应用程序,请重新启动 falcon_app 服务:

sudo systemctl restart falcon_app

要了解有关单元文件的更多信息,请阅读教程 Understanding Systemd Units and Unit files

结论

在本指南中,您配置并部署了您的第一个 Falcon Web 应用程序。 您设置了 Python 环境并在服务器上编写了应用程序代码,然后使用 Gunicorn 为 Web 应用程序提供服务。 然后您配置了 Nginx,以便它将 Web 请求传递给我们的 Gunicorn 应用程序。 最后,您编写了一个 Systemd Unit 文件并启用了该服务,以便您的 Web 应用程序在服务器启动时启动。

当您将自己的应用程序投入生产时,您需要使用主机名而不是 IP 地址来访问它们。 看看 如何使用 DigitalOcean 设置主机名以将您的域名指向您的服务器。