介绍
正如我们在介绍Python的Web服务器比较的文章,uWSGI是一个浩大的工程,能够做比单纯提供Web应用程序的要多得多。 然而,其广泛的功能,配置相对容易,使其成为许多部署需求的极好选择 - 尤其是当它与Nginx耦合。
在这篇DigitalOcean文章中,我们的目标是深入讨论uWSGI,并讨论了不仅仅是安装服务器,而且实际上部署基于各种框架的Python应用程序所需的步骤,涵盖了针对小型,中型甚至相对大型的所有重要步骤生产。
我们还将讨论使用Nginx(以及为什么)使用这个设置,因为Nginx和uWSGI是本地构建的,相互协作,为大多数部署形成完美的。
词汇表
1.了解uWSGI和使用Nginx
- uWSGI简介
- 使用Nginx的Web应用程序部署
- 使用Nginx作为uWSGI的反向代理
2.准备您的Droplet进行生产
- 更新默认操作系统
- 设置Python,pip和virtualenv
- 创建虚拟(Python)环境
- 下载并安装uWSGI
- 下载和安装Nginx
3.使用uWSGI提供Python WSGI应用程序
- WSGI
- WSGI应用对象(可赎回):
wsgi.py
- 运行服务器
- 配置uWSGI
- uWSGI的常见配置
- 使用信号管理uWSGI服务器和进程
4.配置Nginx
5.配置uWSGI
6.生产服务器的其他提示,建议和设置
了解uWSGI和使用Nginx
uWSGI是一个雄心勃勃的项目。 它的工具集允许您做的不仅仅是托管Web应用程序。 因为它做得很好,并且以这种高性能的方式,多年来它已被证明是许多系统管理员和开发人员在部署其应用程序时不可或缺的工具。
Nginx的,因为0.8.40版本支持uwsgi协议 (uWSGI自己的)。 这使得在运行uWSGI沟通可能的Nginx的最好方式WSGI应用。 这对您意味着什么是非常简单的配置部署的可能性,它是高度灵活(和功能),并受益于许多引擎盖下的优化。 总而言之,这使得uWSGI与Nginx耦合成为许多部署场景的绝佳选择。
uWSGI简介
以下是从上述DigitalOcean提取Python的服务器比较的文章:
“尽管它很混乱的命名规则,uWSGI本身就是一个浩大的工程包含多个组件,旨在为建设托管服务提供完整的软件。 其中一个组件,uWSGI服务器,运行Python WSGI应用程序。 它能够使用多种协议,包括自己的uwsgi线协议 ,这是准等同于SCGI的。 为了满足在应用服务器前使用独立HTTP服务器的可理解需求,NGINX和Cherokee Web服务器被模块化,以支持uWSGI的[自己的]最佳性能的uwsgi协议,以直接控制其进程。
uWSGI亮点
uWSGI带有一个WSGI适配器,它完全支持在WSGI上运行的Python应用程序。
它与libpython链接。 它在启动时加载应用程序代码,并像一个Python解释器。 它解析传入的请求并调用Python可调用。
它直接支持流行的NGINX Web服务器(以及Cherokee +和lighttpd)。
它写在C.
它的各种组件可以做更多的运行一个应用程序,这可能是方便的扩展。
目前(截至2013年底),它是积极开发和具有快速释放周期。
它具有用于运行应用程序(异步和同步)的各种引擎。
它可以意味着更低的内存占用运行。
使用Nginx的Web应用程序部署
Nginx是一个非常高性能的Web服务器/(反向)-proxy。 它已经达到了它的普及,由于重量轻,相对容易工作和易于扩展(与附加/插件)。 由于它的结构,它能够处理大量的哪些请求(几乎不受限制)的-这取决于你的应用程序或网站负载-可能是真的很难用一些其他的,旧的替代品来解决。
请记住:“处理”连接技术上意味着不会放弃他们,并能与一些为他们服务。 你仍然需要你的应用程序和数据库运行良好,以使Nginx服务客户端的响应,而不是错误消息。
使用Nginx作为uWSGI的反向代理
许多框架和应用程序服务器可以与来自实际应用程序的响应一起提供静态文件(例如javascript,css,图像等)。 然而,更好的事情是让(反向代理)服务器,如Nginx的处理提供这些文件,并管理连接( 请求 )的任务。 这减轻了应用程序服务器的负载,为您提供了更好的整体性能。
随着应用程序的增长,您将需要优化它,当时间到来时,将它分布在服务器(VPS)上,以便能够同时处理更多的连接,并拥有一个更稳健的架构。 在应用程序服务器前面有一个反向代理可以从一开始就帮助您。
Nginx的可扩展性(例如本地缓存以及故障转移和其他机制)也是一个伟大的壮举,有利于Web应用程序不同于(更简单的)应用程序服务器。
基本服务器体系结构示例:
Client Request ----> Nginx (Reverse-Proxy)
|
/|\
| | `-> App. Server I. 127.0.0.1:8081
| `--> App. Server II. 127.0.0.1:8082
`----> App. Server III. 127.0.0.1:8083
注意:当一个应用程序设置为侦听传入连接127.0.0.1
,就只可能在本地访问它。 如果使用0.0.0.0
,但是,它将接受来自外部的连接以及。
准备您的Droplet进行生产
在本节中,我们将准备我们的虚拟服务器进行生产(即部署我们的应用程序)。
我们将从:
更新默认操作系统
下载和安装常见的Python工具(即pip,virtualenv)
创建一个虚拟环境来包含应用程序(其依赖关系,如uWSGI驻留在其中)
注意:这里给出的说明保持简短。 要了解更多信息,请访问我们的how-to文章PIP和的virtualenv: 常用的Python工具:使用的virtualenv,用Pip安装和管理软件包 。
更新默认操作系统
注意:我们将在一个新的VPS进行以下设置和准备使用的操作系统的最新版本。 在理论上,你不应该在你的服务器上尝试它们有问题。 但是,如果您已经积极使用它,我们强烈建议在尝试之前切换到新系统。
为了确保我们有最新的可用版本的默认应用程序,我们需要更新我们的系统。
对于基于Debian的系统(即Ubuntu,Debian),运行以下命令:
aptitude update
aptitude -y upgrade
对于基于RHEL的系统(即CentOS),运行以下命令:
yum -y update
设置Python,pip和virtualenv
CentOS / RHEL用户注意事项:
CentOS的/ RHEL,默认情况下是作为一个非常精简服务器。 它的工具集,可能会根据您的需要而定,不是运行您的应用程序,而是为服务器的系统工具(例如YUM)供电。
为了准备你的CentOS系统,Python的需要进行设置(即从源代码编译)和PIP / virtualenv中需要使用的解释安装。
要了解如何设置的Python 2.7.6和3.3.3在CentOS 6.4和5.8,与PIP和的virtualenv,请参考: 如何设置的Python 2.7.6和3.3.3在CentOS 。
在Ubuntu和Debian,最近的Python解释器,你可以使用的版本出现在默认情况下。 它使我们只有有限数量的额外的软件包安装:
python-dev(开发工具)
pip(管理包)
virtualenv(创建隔离,虚拟环境)
python-dev:
python-dev的是一个操作系统级的包,其中包含扩展开发工具,用于构建Python模块。
运行以下命令使用aptitude来安装python-dev的:
aptitude install python-dev
pip:
PIP是一个包管理器,它可以帮助我们来安装我们所需要的应用程序包。
运行以下命令安装pip:
curl https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py | python -
curl https://raw.github.com/pypa/pip/master/contrib/get-pip.py | python -
export PATH="/usr/local/bin:$PATH"
您可能需要sudo权限。
virtualenv:
最好是一起包含它自己的环境中的Python应用程序与所有的依赖。 环境可以被最好地描述(简单地)作为一切都驻留的孤立位置(目录)。 为了这个目的,使用了被称为的virtualenv工具。
运行以下命令以安装使用的virtualenv PIP:
sudo pip install virtualenv
创建自包含的虚拟(Python)环境
拥有所有必要的工具,我们可以创建一个环境部署我们的应用程序。
记住:如果你没有得到你的发展的virtualenv(本地)机为你的项目,你应该考虑创建一个,内移动应用程序(及其依赖)。
让我们创造这将包含虚拟环境和应用程序模块的文件夹开始:
您可以在这里使用任何名称,以满足您的需要。
mkdir my_app
我们可以继续输入此文件夹并在其中创建一个新的虚拟环境:
您还可以为虚拟环境选择任何您喜欢的名称。
cd my_app
virtualenv my_app_venv
让我们在那里创建一个新文件夹来包含你的Python应用程序模块:
这是您的应用程序模块将驻留的文件夹。
mkdir app
并激活解释器在虚拟环境中使用它:
请确保使用您选择为您的虚拟环境中,如果你去比“我的应用程序 venv”以外的东西的名称。
source my_app_venv/bin/activate
最后,这是您的主应用程序部署目录应该是什么样子:
my_app # Main Folder to Contain Everything Together
|
|=== my_app_venv # V. Env. folder with the Python Int.
|=== app # Your application module
|..
|.
下载并安装uWSGI
始终是将所有与应用程序相关的元素尽可能多地包含在虚拟环境中的推荐方式。 所以我们将下载并安装uWSGI。
如果你不是一个环境中工作,uWSGI将在全球范围内安装(即提供系统范围)。 这不是建议。 总是选择使用的virtualenv。
要使用pip安装uWSGI,请运行以下命令:
pip install uwsgi
记住:要了解更多关于点子 ,它的用法和功能,请参考下面的文章常用的Python工具:使用的virtualenv,用Pip安装和管理软件包 。
下载和安装Nginx
CentOS / RHEL用户注意事项:
以下说明不适用于CentOS系统。 请参阅说明书在这里为CentOS。
运行以下命令来使用默认的系统包管理器安装资质的 Nginx的:
sudo aptitude install nginx
要运行Nginx,您可以使用以下命令:
sudo service nginx start
要停止Nginx,可以使用以下命令:
sudo service nginx stop
要重新启动Nginx,您可以使用以下命令:
每次重新配置Nginx后,需要重新启动或重新加载以使新设置生效。
sudo service nginx restart
注意:要了解更多关于Nginx的在Ubuntu,请参阅文章: 如何在Ubuntu 12.04安装Nginx的 。
使用uWSGI提供Python WSGI应用程序
在本节中,我们将看到Python WSGI应用程序如何与uWSGI Web服务器配合使用。 使用uWSGI来提供Python WSGI应用程序与其他应用程序容器不同。 uWSGI需要什么,就像其他服务器,是您的应用程序为它提供一个入口点( 可调用 )。 在启动期间,这个可调用以及配置变量被传递给uWSGI,它开始执行它的工作。 当请求到达时,它处理它并将其传递到应用程序的控制器来处理。
建筑:
........
/|\
| | `-> App. Server I. 127.0.0.1:8080 <--> Application
| `--> App. Server II. 127.0.0.1:8081 <--> Application
.....
WSGI
简而言之,WSGI是Web服务器和应用程序本身之间的接口。 它的存在是为了保证各种服务器和应用程序(框架)之间的标准化的方式彼此合作,允许互换性必要时(例如,从开发切换到生产环境),这是一个必须有需要时下。
注意:如果你有兴趣了解更多关于WSGI和Python的Web服务器 ,看看我们的文章: 网络服务器的基于Python的Web应用程序的比较 。
WSGI应用程序对象(可调用):“wsgi.py”
如上所述,在WSGI上运行的Web服务器需要一个应用程序对象(即您的应用程序)。
与大多数框架和应用,这是由一个wsgi.py的遏制和提供由服务器一起使用的应用程序对象(或调用)。
我们将开始创建一个示例性的wsgi.py,然后将被导入并由uWSGI用来运行应用程序。
您可以选择任何名称,而不是wsgi.py。 然而,这些是通常使用的(例如通过Django)。
让我们开始创建一个wsgi.py文件来包含一个基本的WSGI应用程序。
运行以下命令以使用文本编辑器nano创建wsgi.py:
nano wsgi.py
让我们继续移动(复制/粘贴)基本的WSGI应用程序代码(应该替换为你自己的应用程序可调用的生产):
def application(env, start_response):
start_response('200 OK', [('Content-Type', 'text/html')])
return ["Hello!"]
这是由服务器,每一个请求到来时包含的文件,服务器使用这个应用程序在调用解析URL来运行应用程序的请求处理程序(即控制器 )(如mysite.tld /控制器/方法/变量)。
将应用程序代码放入后,按CTRL + X,然后用Y确认,将此文件保存在虚拟环境旁边的“my_app”文件夹中,以及包含实际应用程序的应用程序模块。
注:此应用程序WSGI是最基本的例子,它的种类。 您将需要替换此代码块,以包含应用程序模块中自己的应用程序对象。
一旦完成,这就是您的主应用程序部署目录应该是什么样子:
my_app # Main Folder to Contain Everything Together
|
|=== my_app_venv # V. Env. folder with the Python Int.
|=== app # Your application module
|
|--- wsgi.py # File containing application callable
|..
|.
运行服务器
uWSGI有很多选项和配置,有许多可能的使用方法,由于它的灵活性。 从一开始就没有复杂的事情,我们将开始使用它尽可能简单,并继续使用更先进的方法。
简单用法示例:
uwsgi [option] [option 2] .. -w [wsgi file with app. callable]
要简单地运行uWSGI从wsgi.py开始提供应用程序,请运行以下命令:
uwsgi --socket 127.0.0.1:8080 --protocol=http -w wsgi
这将在前台运行服务器。 如果你想停止它,按CTRL + C。
要在后台运行服务器,请运行以下命令:
uwsgi --socket 127.0.0.1:8080 --protocol=http -w wsgi &
重要事项[!]:当你运行服务器使用Nginx的配置从部分配置Nginx的工作,请务必取出--protocol=http
从参数的链条,否则Nginx的和uWSGI将无法搭腔其他。
当您在后台运行应用程序时,您需要使用进程管理器(例如htop)来终止(或停止)它。 有关详细信息,请参阅下面的部分。
使用信号管理uWSGI服务器和进程
管理uWSGI由运行时执行的操作组成。 为此任务设置了各种命令以操作该过程:
SIGHUP
-HUP
优雅地重新加载工人和应用SIGTERM
-TERM
“惨遭”重新加载SIGINT
-INT
和SIGQUIT-QUIT
杀死立即全体职工SIGUSR1
-USR1
提供的统计数据(标准输出)SIGUSR2
-USR2
打印工人身份SIGURG
-URG
恢复快照SIGTSTP
-TSTP
暂停,暂停或恢复实例SIGWINCH
-WINCH
唤醒阻塞在系统调用工人
带信号的示例管理:
使用SIGHUP重新启动服务器
此命令正常重新启动服务器。 这意味着,它等待当前工作的工作完成,然后终止它们,然后再次生成它们,继承其设置。
用法: kill -HUP [PID]
如果你不想指定PID,则可以使用
pidfile
选项,uWSGI它写入一个文件,然后您可以用它来管理的进程。
使用SIGINT停止服务器
要停止服务器及其过程,你需要使用-INT
信号。 这将在后台终止一切。
例如: kill -INT [PID]
配置Nginx
在设置uWSGI来运行我们的应用程序后,我们现在需要对Nginx做同样的工作,以便与uWSGI服务器通信。 对于这一点,我们需要修改Nginx的配置文件: nginx.conf
运行以下命令来打开nginx.conf
并采用纳米文本编辑器编辑:
sudo nano /etc/nginx/nginx.conf
之后,您可以使用以下示例配置替换文件,以使Nginx作为反向代理工作,与您的应用程序通信。
注意:要了解结合SSL支持,请先看看这篇文章: 创建于Nginx的SSL证书 。
Web应用程序的示例配置:
worker_processes 1;
events {
worker_connections 1024;
}
http {
sendfile on;
gzip on;
gzip_http_version 1.0;
gzip_proxied any;
gzip_min_length 500;
gzip_disable "MSIE [1-6]\.";
gzip_types text/plain text/xml text/css
text/comma-separated-values
text/javascript
application/x-javascript
application/atom+xml;
# Configuration containing list of application servers
upstream uwsgicluster {
server 127.0.0.1:8080;
# server 127.0.0.1:8081;
# ..
# .
}
# Configuration for Nginx
server {
# Running port
listen 80;
# Settings to by-pass for static files
location ^~ /static/ {
# Example:
# root /full/path/to/application/static/file/dir;
root /app/static/;
}
# Serve a static file (ex. favico) outside static dir.
location = /favico.ico {
root /app/favico.ico;
}
# Proxying connections to application servers
location / {
include uwsgi_params;
uwsgi_pass uwsgicluster;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}
}
完成修改配置后,按CTRL + X并使用Y确认以保存并退出。 您将需要重新启动Nginx以使更改生效。
运行以下命令重启Nginx:
sudo service nginx stop
sudo service nginx start
注意:要了解更多关于Nginx的,请参阅文章: 如何在VPS配置的Nginx Web服务器 。
配置uWSGI
当启动uWSGI服务应用程序时,有几种方法为它提供必要的配置,如运行的套接字,进程数,主进程设置等。在本节中,我们将讨论其中三个:
将配置作为参数传递
使用
.ini
文件的配置使用
.json
文件进行配置
注:uWSGI支持各种协议和方式来检索,如标准输入和HTTP这些配置文件。
选项#1:传递配置作为参数:
虽然容易混乱,有时很难管理,运行uWSGI的最基本的方法就像任何其他shell脚本 - 通过提供必要的配置作为参数。
用法示例:
# uwsgi [option] [option 2] .. -w [wsgi.py with application callable]
# Simple server running *wsgi*
uwsgi --socket 127.0.0.1:8080 -w wsgi
# Running Pyramid (Paster) applications
uwsgi --ini-paste production.ini
# Running web2py applications
uwsgi --pythonpath /path/to/app --module wsgihandler
# Running WSGI application with specific module / callable names
uwsgi --module wsgi_module_name --callable application_callable_name
uwsgi -w wsgi_module_name:application_callable_name
有关如何运行uWSGI更多的例子,考虑访问其文档, 示例配置 。
选项2:使用.ini
文件的配置
提供uWSGI与配置的另一个(可能)更好的方式是通过.ini
文件。 这些文件具有简单的结构(请参见下面的示例),并且需要在每次执行uWSGI启动脚本时显式传递。
实例.ini
结构(example_config.ini):
[uwsgi]
# -------------
# Settings:
# key = value
# Comments >> #
# -------------
# socket = [addr:port]
socket = 127.0.0.1:8080
# Base application directory
# chdir = /full/path
chdir = /my_app
# WSGI module and callable
# module = [wsgi_module_name]:[application_callable_name]
module = app:application
# master = [master process (true of false)]
master = true
# processes = [number of processes]
processes = 5
..
用法示例:
uwsgi --ini example_config.ini
选项#3:使用.json
文件进行配置
同工作.json
文件是,除了从结构,与上述相同示出的例子。
例如.json
结构(example_config.json):
{
"uwsgi": {
"socket": ["127.0.0.1:8080"],
"module": "my_app:app",
"master": true,
"processes": 5,
}
}
用法示例:
uwsgi --json example_config.json
要了解更多关于配置uWSGI,可以阅读其文档配置 。
uWSGI的常见配置
默认情况下,此服务器默认设计为框架/应用程序/平台不可知。 虽然它可能支持任何您可能需要的东西,但是某些选项需要明确设置以符合您的要求。
如其自己的文档中所述,配置uWSGI的可能方法的数量几乎是无限的。 在本节中,我们将尝试讨论最常用或重要的,并解释实现,当与上一节结合时,将使您能够使uWSGI完全按照您的需要运行。
有关优化,请参阅本节后面的下一节。
在下面的实施例中使用的语法被针对.ini
文件。 您可以修改它们来满足您的特定需求,根据需要(例如, .json
基础配置,如在上一节中介绍)。
插座
http-socket
将uWSGI设置为绑定到某个HTTP套接字。
例如: http-socket = :8080
插座
使用默认协议将uWSGI设置为绑定到指定的套接字。
例如: socket = 127.0.0.1:8080
过程(工人)
任一术语可以用于指代相同的事:进程的量衍生的接受请求 。
例如: processes = 5
协议
缺省情况下,uWSGI运行在其自己的uwsgi协议。 该属性允许您更改它。
例如: protocol = http
管理
主
此选项用于启用或禁用主uWSGI进程。 这些进程用于管理接受和处理传入请求的工人。 优点很多,包括优雅地重新启动工人,而不Touch插座,这将允许您无需停机升级。
例如: master = true
最大请求
如果你担心内存泄漏,并且不能想到一个更加坚实的处理它的方法,这个选项将允许你在处理设置的请求数量后自动重新启动你的进程。
例如: max-requests = 1001
线程
在重新线程模式下使用指定数量的线程运行每个进程的设置。 这是可能与处理此选项,以获得不同程度的并行结合。
例如: threads = 2
记录
禁用日志
用于禁用日志记录功能。
例如: disable-logging = true
uWSGI过程
procname
允许您将进程名称设置为您选择的进程名称。
例如: procname = My Application
uid
设置uWSGI服务器用户uid
到指定的一个。
例如: uid = 1001
gid
设置uWSGI服务器gid
到指定的一。
例如: gid = 555
真空
退出时删除所有生成的pidfiles / sockets。
守护进程
此设置daemonizes uWSGI和提供的参数(日志文件)写入消息。
例如: daemonize = /tmp/uwsgi_daemonize.log
pidfile
设置uWSGI以将过程PID写入由选项指定的文件。 这个选项是用于运行uWSGI流程的管理非常方便(详见信息管理uWSGI部分)。
例如: pidfile = /tmp/proj_pid.pid
各种
harakiri
此设置用于设置时间允许进程完成任务之前被杀死,回收内存/管理目的的最高数额。
例如: harakiri = 30
要了解所有可用的数百个配置,你应该读检查位于官方的完整列表的配置选项文件。
其他提示和建议
防火墙:
保护SSH:
创建警报:
监视和监视服务器访问日志每日: