如何在Ubuntu16.04上使用Gunicorn和Nginx部署FalconWeb应用程序
介绍
Falcon 是一个用于构建 Web 应用程序的最小 Python 框架。 它非常适合构建遵循 REST 架构风格的 API。 它是一个低级、高性能的框架,它试图在不牺牲开发速度的情况下做尽可能少的事情。
在本教程中,您将构建和部署 Falcon Web 应用程序。 Falcon 是一个 WSGI 框架,因此您将安装和使用 Gunicorn,一个 WSGI 应用程序服务器,为应用程序提供服务。 然后,您将创建一个使用 Nginx 作为反向代理服务器的生产就绪环境,以在传入请求到达 Gunicorn 之前对其进行处理。
先决条件
要完成本教程,您需要:
- 按照 Ubuntu 16.04 初始服务器设置指南 设置一台 Ubuntu 16.04 服务器,包括 sudo 非 root 用户和防火墙。
第 1 步——创建 Python 虚拟环境
在我们开始编写代码或设置服务之前,我们将在服务器上为我们的应用程序创建一个 Python 虚拟环境。
以非 root 用户身份连接到您的服务器:
ssh sammy@your_server_ip
Falcon 适用于 Python 2.x 和 Python 3.x,但我们将使用 Ubuntu 16.04 中可用的最新 Python 版本,即 Python 3.5。
我们将使用 pip 和 virtualenv 来设置我们的 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 时,就会调用 TestResource
的 on_get()
方法。 响应状态和正文分别使用变量 res.status
和 res.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
。
ExecReload
和 ExecStop
变量定义了服务应该如何启动和停止。
最后,我们添加 [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 设置主机名以将您的域名指向您的服务器。