如何使用 uWSGI Web 服务器和 Nginx 部署 Python WSGI 应用程序

介绍


正如我们在我们的 Python Web Server Comparison文章中所介绍的那样,uWSGI是一个庞大的项目,能够做得比单独服务Web应用程序要多得多。

在这篇DigitalOcean文章中,我们旨在深入讨论uWSGI,并探讨不仅安装服务器,而且实际部署基于各种框架的Python应用程序的必要步骤,涵盖小型,中型,甚至相对大型的生产的每一个重要步骤。

我们还将讨论使用 Nginx(以及为什么)在这个设置中,因为 Nginx 和 uWSGI 是原生构建的,以便彼此合作,为大多数部署形成完美的堆栈。

词汇


1.理解uWSGI和使用nginx


  1. uWSGI 简介 2. 使用 Nginx 部署 Web 应用程序 3. 使用 Nginx 作为 uWSGI 的反向代理

2 准备你的滴滴来生产


  1. 更新默认操作系统 2. 设置 Python、pip 和 virtualenv 3. 创建虚拟 (Python) 环境 4. 下载和安装 uWSGI 5. 下载和安装 Nginx

3. 使用 uWSGI 服务 Python WSGI 应用程序


  1. WSGI 2. WSGI 应用对象(可调用): wsgi.py 3. 运行服务器 4. 配置 uWSGI 5. 用于 uWSGI 的常见配置 6. 使用信号管理 uWSGI 服务器和流程

4 配置 Nginx

5 配置 uWSGI

6. 混淆的提示,建议和设置为生产服务器

了解 uWSGI 和使用 Nginx


uWSGI是一个雄心勃勃的项目. 它的工具集允许您做得不仅仅是托管Web应用程序。 由于它做得很好,并且以如此高效的方式,多年来它已被证明是许多系统管理员和开发人员在部署应用程序时不可或缺的工具。

Nginx,因为版本 0.8.40 支持 uwsgi 协议 (uWSGI 自己的)。 这使运行在 uWSGI 上的 WSGI 应用程序能够以最好的方式与 Nginx 进行通信. 这对于您来说意味着非常简单的配置部署的可能性,这些部署非常灵活(和功能),并受益于许多随之而来的优化。

简介 简介


以下是上述DigitalOcean Python Server Comparison文章的摘要:

尽管其命名惯例非常混乱,uWSGI本身是一个具有许多组成部分的庞大项目,旨在为建设_宿主服务提供完整的软件堆. 其中之一的uWSGI服务器运行了Python WSGI应用程序. 它能够使用各种协议,包括它自己的_uwsgi电线协议_,它与SCGI准同. 为了满足在应用程序服务器前使用独立的HTTP服务器这一可以理解的需求,NGINX和切罗基网络服务器被模块化,以支持uWSGI的[自有]性能最好的uwsgi协议来直接控制其进程.

主持人:UWSGI Highlights

*uWSGI带有WSGI适配器,它完全支持在WSGI上运行的Python应用程序.

  • 联合国 它和利平通有关 它在启动时加载应用程序代码,并起到像Python解释器的作用. 它解析了收到的请求并引用了可调用的 Python 。
  • 联合国 它直接支持流行的NGINX网络服务器(与切罗克+和Lighttpd同时).
  • 联合国 其文为C.
  • 联合国 其各种组件所能做的远不止运行一个应用程序,它可能有利于扩展.
  • 目前(截至2013年底),它正在积极开发,并且有快速的释放周期。
  • 联合国 它拥有各种运行应用(同步和同步)的引擎.
  • 联合国 可以指: 更低的内存足迹来跑. .

使用 Nginx 部署 Web 应用程序


Nginx 是一个非常高性能的 Web 服务器 / (反向) - 代理服务器. 它因其轻量,相对易于使用和易于扩展(通过插件 / 插件)而获得了其受欢迎性。 由于其架构,它能够处理 a lot 请求(几乎无限),这 - 取决于您的应用程序或网站的负载 - 可能很难使用其他一些较旧的替代方案来解决。

记住:处理连接在技术上意味着不放弃它们,并且能够为它们提供 something 服务. 您仍然需要您的应用程序和数据库正常工作,以便 Nginx 服务客户的响应不是错误消息。

使用 nginx 作为 uWSGI 的反向代理


许多框架和应用程序服务器可以与实际应用程序的响应一起服务静态文件(例如 javascript、css、图像等)。

随着应用程序的增长,您将希望优化它,并在时间到来时,在服务器(VPS)之间分发它,以便能够同时处理更多的连接,并具有更强大的架构。

Nginx的可扩展性(例如,原生缓存以及故障转移和其他机制)也是一个很好的成就,这与(简单)应用服务器不同,有利于Web应用程序。

** 基本服务器架构的示例:**

1Client Request ----> Nginx (Reverse-Proxy)
2                        |
3                       /|\                           
4                      | | `-> App. Server I. 127.0.0.1:8081
5                      |  `--> App. Server II. 127.0.0.1:8082
6                       `----> App. Server III. 127.0.0.1:8083

** 注意:** 当应用程序设置为听取127.0.0.1上的接入连接时,只能在本地访问它。

为生产准备您的滴滴


在本节中,我们将准备我们的虚拟服务器进行生产(即部署我们的应用程序)。

我们将从:

*更新默认操作系统 *下载和安装常见的Python工具(即Pip,virtualenv) *创建一个虚拟环境以包含应用程序(其依赖性如uWSGI的内部)

** 注意: ** 这里提供的指示是简短的。 要了解更多信息,请参阅我们关于 pipvirtualenv 的文章: 常见的 Python 工具:使用 virtualenv,安装与 Pip 和管理包

更新默认操作系统


** 注意:** 我们将使用最新版本的操作系统在新的 VPS 上执行以下设置和准备工作。理论上,您不应该有问题在您的服务器上尝试它们。

为了确保我们拥有最新的默认应用程序版本,我们需要更新我们的系统。

对于基于 Debian 的系统(即 Ubuntu、Debian),请执行以下操作:

1aptitude update
2aptitude -y upgrade

对于基于RHEL的系统(即CentOS),运行以下操作:

1yum -y update

设置 Python、Pip 和 virtualenv


翻译: ** CentOS / RHEL 用户说明:** 翻译: ** CentOS / RHEL** ,默认为作为非常精细的服务器而来. 它的工具集,很可能是为了满足您的需要而过时的,它不是运行您的应用程序,而是为服务器的系统工具(如YUM)提供动力. 翻译: 翻译: 为了准备您的 CentOS 系统, Python 需要设置( 即从源头编译) , ** pip ** / ** virtualeenv ** 需要使用该解释器安装 。 翻译: 翻译: 欲了解如何在CentOS 6.4和5.8 上设置Python 2.7.6和3.3.3,并附有pip和vitualenv,请参见:[如何在CentOS上设置Python 2.7.6和3.3.3] (https://www.digitalocean.com/community/articles/how-to-set-up-python-2-7-6-and-3-3-3-on-centos-6-4).

在Ubuntu和Debian上,你可以使用的Python翻译器的最新版本是默认的,它只留给了我们一个有限的额外包来安装:

  • python-dev (开发工具) * pip (管理包) * virtualenv (创建孤立的虚拟环境)

主題: python-dev

python-dev 是一个操作系统级包,包含用于构建 Python 模块的扩展开发工具。

运行以下命令以使用 aptitude 安装 python-dev:

1aptitude install python-dev

:

pip 是一个包管理器,可以帮助我们安装我们需要的应用程序包。

运行以下命令来安装 pip:

1curl https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py | python -
2curl https://raw.github.com/pypa/pip/master/contrib/get-pip.py | python -
3export PATH="/usr/local/bin:$PATH"

您可能需要 sudo 特权。

虚拟化:

最好将一个Python应用程序包含在其自身的 environment 内,以及其所有依赖性。 一个环境可以最好地描述(简单地说)作为一个孤立的位置(一个目录),其中一切都在。

运行以下操作以使用 pip 安装 ** virtualenv** :

1sudo pip install virtualenv

创建一个自有的虚拟(Python)环境


有了所有必要的工具,我们可以创建一个环境来部署我们的应用程序。

** 请记住:** 如果您没有在您的开发(本地)机器上有一个虚拟机,您应该考虑创建一个,并将您的应用程序(及其依赖)移动到内部。

让我们先创建一个包含 virtual environmentyour application module 的文件夹:

您可以在这里使用任何名称来满足您的需求。

1mkdir my_app

我们可以继续输入此文件夹并在里面创建一个新的虚拟环境:

您也可以为您的虚拟环境选择您喜欢的任何名称。

1cd my_app
2virtualenv my_app_venv

让我们在那里创建一个新的文件夹,以包含您的Python应用模块:

这是您的应用模块将居住的文件夹。

1mkdir app

** 并在虚拟环境中激活翻译器以使用它:**

请确保使用您选择的虚拟环境的名称,如果您选择了my_app_venv

1source my_app_venv/bin/activate

** 最后,这是你的主要应用部署目录应该是这样的:**

1my_app              # Main Folder to Contain Everything Together
2  |
3  |=== my_app_venv  # V. Env. folder with the Python Int.
4  |=== app          # Your application module
5  |..
6  |.

下载和安装 uWSGI


它始终是建议的方式来包含所有应用程序相关的元素,尽可能多,在虚拟环境中一起,所以我们将下载和安装uWSGI作为这样的。

如果您不在环境中工作,则 uWSGI 将安装 globally (即在整个系统中可用)。

** 若要使用 pip 安装 uWSGI,请执行以下操作:**

1pip install uwsgi

** 请记住:** 若要了解更多关于 pip 的信息、其使用和功能,请参阅以下文章: Common Python Tools: Using virtualenv, Installing with Pip, and Managing Packages

下载和安装 Nginx


** 注意 CentOS / RHEL 用户:** > > 下面的指示不会在 CentOS 系统上工作. 请参阅 CentOS 的指示 这里

** 运行以下命令以使用默认系统包管理器 aptitude install Nginx:**

1sudo aptitude install nginx

** 要运行 Nginx,您可以使用以下方法:**

1sudo service nginx start

** 要停止 Nginx,您可以使用以下方法:**

1sudo service nginx stop

** 若要重新启动 Nginx,您可以使用以下方法:**

每次重新配置 Nginx 后,需要重新启动或重新加载才能使新设置生效。

1sudo service nginx restart

** 注意:** 若要了解有关 Ubuntu 上 Nginx 的更多信息,请参阅我们的文章: 如何在 Ubuntu 12.0 上安装 Nginx

服务 Python WSGI 应用程序与 uWSGI


在本节中,我们将看到一个Python WSGI应用程序如何与uWSGI网络服务器工作. 与uWSGI合作为Python WSGI应用服务,与其他应用容器并不相异. uWSGI 需要的,就像其他服务器一样,是供您的应用程序为它提供切入点(a callable). 在发射时,这个可调用器与配置变量一起被传递给uWSGI,并开始工作. 当一个请求到达时,它会处理它,并传递给您的应用程序控制器处理.

建筑设计:**

1........
2      /|\                           
3     | | `-> App. Server I. 127.0.0.1:8080  <--> Application
4     |  `--> App. Server II. 127.0.0.1:8081  <--> Application
5      .....

名称:WSGI


简而言之,WSGI是网络服务器和应用程序本身之间的接口,它存在于确保各种服务器和应用程序(框架)之间相互工作的标准化方式,在必要时允许互换性(例如从开发到生产环境的切换),这是今天必需的。

注: 如果您有兴趣了解更多关于 ** WSGI** 和 ** Python Web 服务器** 的信息,请参阅我们的文章: Python 基于 Web 应用程序的 Web 服务器比较

WSGI 应用对象(可调用): wsgi.py


如上所述,在 WSGI 上运行的 Web 服务器需要一个应用程序对象(即应用程序的对象)。

对于大多数框架和应用程序,这包括一个 **wsgi.py 以包含和提供一个应用程序对象(或可调用)用于服务器。

我们将开始创建一个典型的 wsgi.py,然后将被 uWSGI 导入并使用来运行应用程序。

您可以选择任何名称而不是 wsgi.py. 然而,这些是常用的名称(例如,由Django)。

让我们先创建一个 wsgi.py 文件以包含一个基本的 WSGI 应用程序。

** 运行以下命令以使用文本编辑器 nano 创建 wsgi.py:**

1nano wsgi.py

让我们继续移动(复制/粘贴)内部的基本WSGI应用程序代码(该代码应该被你自己的应用程序的可调用代码取代):

1def application(env, start_response):
2    start_response('200 OK', [('Content-Type', 'text/html')])
3    return ["Hello!"]

这是服务器所包含的文件,每次发出请求时,服务器都会使用该应用程序可调用来运行应用程序的请求处理器(即 controllers )来解析 URL(例如 mysite.tld/controller/method/variable)。

插入应用程序代码后,按 CTRL + X,然后用 Y 确认,以便在虚拟环境和包含实际应用程序的应用程序模块旁边的my_app文件夹中保存该文件。

** 注意:** 此 WSGI 应用程序是其类型的最基本的例子,您需要更换此代码块以从应用程序模块中包含自己的应用程序对象。

一旦完成,这就是您的主要应用部署目录应该是这样的:

1my_app              # Main Folder to Contain Everything Together
2  |
3  |=== my_app_venv  # V. Env. folder with the Python Int.
4  |=== app          # Your application module
5  |
6  |--- wsgi.py      # File containing application callable
7  |..
8  |.

运行服务器


uWSGI有许多选项和配置,由于其灵活性,有许多可能的方式来使用它们. 没有从一开始就复杂的事情,我们将开始尽可能简单地处理它,并继续使用更先进的方法。

简单的使用例子:**

1uwsgi [option] [option 2] .. -w [wsgi file with app. callable]

** 要简单地运行 uWSGI 以便从 wsgi.py 开始服务应用程序,请执行以下操作:**

1uwsgi --socket 127.0.0.1:8080 --protocol=http -w wsgi

这将使服务器在前台运行. 如果您想阻止它,请按 CTRL+C。

** 要在背景中运行服务器,请执行以下操作:**

1uwsgi --socket 127.0.0.1:8080 --protocol=http -w wsgi &

[!] 重要: 当您运行服务器以使用部分 ** Configuring Nginx** 中的配置来与 Nginx 工作时,请确保从参数链中删除 `--protocol=http,否则 Nginx 和 uWSGI 将无法彼此交谈。

当您在背景中运行应用程序时,您需要使用一个流程管理器(例如 htop)来杀死(或停止)它。

使用信号管理 uWSGI 服务器和流程


管理 uWSGI 由运行时所采取的操作组成,为此任务设置了各种命令来操纵过程:

  • SIGHUP -HUP优雅地重新加载了工人和应用程序 * ** SIGTERM** -TERM``残酷地重新加载 * ** SIGINT** -INT 和 ** SIGQUIT** -QUIT 立即杀死了所有工人 * ** SIGUSR1** -USR1 打印了统计数据 (stdout) * ** SIGUSR2** -USR2 打印了工人状态 * ** SIGURG** -URG 恢复了快照 * ** SIGTSTP** -TSTP 暂停,暂停或恢复了实例 SIG ** WINCH* -WINCH 唤醒了一个在 syscall 中封锁的工人

与信号的示例管理:

使用 SIGHUP 重新启动服务器

这个命令优雅地重新启动服务器,这意味着它等待当前工人的工作完成,然后结束他们,然后再生它们,继承其设置。

使用: 杀死 -HUP [PID]`

如果您不希望指定 PID,您可以使用pidfile选项让 uWSGI 将其写成文件,然后您可以使用它来管理流程。

用 SIGINT 关闭服务器

要停止服务器及其流程,您需要使用-INT信号,这将终止背景中的所有东西。

杀人为例。

配置 Nginx


在设置 uWSGI 来运行我们的应用程序后,我们现在需要与 Nginx 做同样的事情,以便它可以与 uWSGI 服务器(s)交谈。

** 运行以下命令,打开「nginx.conf」并使用纳米文本编辑器编辑它:**

1sudo nano /etc/nginx/nginx.conf

之后,您可以用以下示例配置来替换文件,以便 Nginx 作为反向代理程序工作,与您的应用程序交谈。

** 注意:** 若要了解如何嵌入 SSL 支持,请先阅读本文: 在 Nginx 上创建 SSL 证书

** Web 应用程序的示例配置:**

 1worker_processes 1;
 2
 3events {
 4
 5    worker_connections 1024;
 6
 7}
 8
 9http {
10
11    sendfile on;
12
13    gzip on;
14    gzip_http_version 1.0;
15    gzip_proxied any;
16    gzip_min_length 500;
17    gzip_disable      "MSIE [1-6]\.";
18    gzip_types text/plain text/xml text/css
19                      text/comma-separated-values
20                      text/javascript
21                      application/x-javascript
22                      application/atom+xml;
23
24    # Configuration containing list of application servers
25    upstream uwsgicluster {
26
27        server 127.0.0.1:8080;
28        # server 127.0.0.1:8081;
29        # ..
30        # .
31
32    }
33
34    # Configuration for Nginx
35    server {
36
37        # Running port
38        listen 80;
39
40        # Settings to by-pass for static files 
41        location ^~ /static/  {
42
43            # Example:
44            # root /full/path/to/application/static/file/dir;
45            root /app/static/;
46
47        }
48
49        # Serve a static file (ex. favico) outside static dir.
50        location = /favico.ico  {
51
52            root /app/favico.ico;
53
54        }
55
56        # Proxying connections to application servers
57        location / {
58
59            include uwsgi_params;
60            uwsgi_pass uwsgicluster;
61
62            proxy_redirect off;
63            proxy_set_header Host $host;
64            proxy_set_header X-Real-IP $remote_addr;
65            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
66            proxy_set_header X-Forwarded-Host $server_name;
67
68        }
69    }
70}

当您完成更改配置时,请按 CTRL + X 并用 Y 确认保存和退出,您需要重新启动 Nginx 以便更改生效。

** 运行以下操作来重新启动 Nginx:**

1sudo service nginx stop
2sudo service nginx start

** 注意:** 有关 Nginx 的更多信息,请参阅我们的文章: 如何在 VPS 上配置 Nginx Web Server

配置 uWSGI


在启动 uWSGI 来服务应用程序时,有几种方法可以为其提供必要的配置,例如要运行的插槽、流程数量、主流程设置等。

  • 通过配置作为参数 * 使用 .ini 文件进行配置 * 使用 .json 文件进行配置

注意: uWSGI 支持各种协议和方法来检索这些配置文件,如 stdinHTTP

** 选项 # 1:将配置作为参数:**

虽然易于混淆,有时很难管理,但运行 uWSGI 的最基本方法就像任何其他壳脚本一样 - 通过为其提供必要的配置作为论点。

使用例子:

 1# uwsgi [option] [option 2] .. -w [wsgi.py with application callable]
 2
 3# Simple server running *wsgi*
 4uwsgi --socket 127.0.0.1:8080 -w wsgi
 5
 6# Running Pyramid (Paster) applications
 7uwsgi --ini-paste production.ini
 8
 9# Running web2py applications
10uwsgi --pythonpath /path/to/app --module wsgihandler
11
12# Running WSGI application with specific module / callable names
13uwsgi --module wsgi_module_name --callable application_callable_name
14uwsgi -w wsgi_module_name:application_callable_name

有关如何运行 uWSGI 的更多示例,请参阅其文档 示例配置

** 选项 # 2:使用.ini 文件进行配置**

另一种(也许)更好的方法是通过.ini 文件提供 uWSGI 配置,这些文件具有简单的结构(见下面的示例),每次执行 uWSGI 启动脚本时都需要明确地通过。

例如.ini 结构(example_config.ini ):

 1[uwsgi]
 2# -------------
 3# Settings:
 4# key = value
 5# Comments >> #
 6# -------------
 7
 8# socket = [addr:port]
 9socket = 127.0.0.1:8080
10
11# Base application directory
12# chdir = /full/path
13chdir  = /my_app
14
15# WSGI module and callable
16# module = [wsgi_module_name]:[application_callable_name]
17module = app:application
18
19# master = [master process (true of false)]
20master = true
21
22# processes = [number of processes]
23processes = 5
24
25..

使用例子:

1uwsgi --ini example_config.ini

** 选项 # 3:使用.json 文件进行配置**

与.json 文件一起工作,除了结构外,与上面的示例相同。

例如 .json 结构(example_config.json ):

1{
2    "uwsgi": {
3        "socket": ["127.0.0.1:8080"],
4        "module": "my_app:app",
5        "master": true,
6        "processes": 5,
7    }
8}

使用例子:

1uwsgi --json example_config.json

要了解有关 uWSGI 配置的更多信息,请考虑阅读其 配置的文档。

uWSGI 的常见配置


默认情况下,这个服务器的设计是框架 / 应用程序 / 平台无知的默认情况下. 虽然它可能支持任何你可能需要的一切,但某些选项需要明确设置以满足你的要求。

正如其自己的文档所指出的那样,配置 uWSGI 的可能方式几乎是无限的. 在本节中,我们将尝试探讨最常用的或关键的,并解释实施,这在与上一节相结合时,将使 uWSGI 能够以您需要的方式运行。

对于优化,请参阅本节之后的下一节。

在下面的示例中使用的语法针对 .ini 文件,您可以根据自己的具体需求进行修改(如在上一节所解释的 .json 基于配置)。

主持人:Sockets

主页 > HTTP Socket

设置 uWSGI 连接到特定 HTTP 接口。

例如: http-socket = :8080

主持人:Socket

设置 uWSGI 以使用默认协议绑定到指定的插槽。

例如: 插槽 = 127.0.0.1:8080

工人(工人)

任何一个术语都可以用来指相同的东西:接受 requests 所产生的过程数量。

例子:过程 = 5

简介: 协议

默认情况下,uWSGI 运行其自己的 uwsgi 协议,此属性允许您更改它。

例如: 协议 = HTTP

管理

主持人*

此选项用于启用或禁用主 uWSGI 流程. 这些流程用于管理接受和处理接入请求的员工. 优点有很多,包括优雅地重新启动工人而不触摸插头,这将允许您升级而无需停机时间。

例子:大师 = 真

请求 max 请求

如果您担心内存泄露,并且无法想象一种更坚实的方法来处理它,此选项将允许您在处理指定请求数量后自动重新启动流程。

例如: max-requests = 1001

threads

设置以在重读模式中运行指定数量的线程的每个进程,可以将此选项与 进程 相结合,以获得不同程度的兼并。

例子:‘threads = 2’

主页 > 登录 >

• 禁用日志

被用来禁用登录功能。

示例:「禁用日志 = true」

uWSGI 流程

名称 名称

允许您将过程名称设置为您选择的东西。

示例:‘procname = 我的应用程序’

uid

将 uWSGI 服务器用户uid设置为指定的一个。

例子:UID = 1001

gid

将 uWSGI 服务器gid设置为指定的服务器。

例子:‘gid = 555’

• 真空

在输出时删除所有生成的Pidfiles/Sockets。

主持人:Demonize

此设置 daemonizes uWSGI,并将消息写入所提供的参数(日志文件)。

例如: daemonize = /tmp/uwsgi_daemonize.log

pidfile

将 uWSGI 设置为将进程 PID 写入该选项所指定的文件. 此选项对于管理正在运行的 uWSGI 进程非常方便(请参阅 管理 uWSGI 部分以获取更多信息)。

例如: pidfile = /tmp/proj_pid.pid

◎多种多样的**

哈拉基里 哈拉基里

此设置用于设置一个过程完成其任务的最大时间 在它被杀死和回收 为记忆 / 管理目的之前。

例子:‘哈拉基里 = 30’

要了解有关数百种可用的配置的所有信息,请查看位于官方 配置选项文档的完整列表。

混淆的提示和建议


防火墙:

安全的SSH:

创建警报:**

** 每天监控和观看服务器访问日志:**

Submitted by: O.S. Tezer
Published At
Categories with 技术
comments powered by Disqus