Nginx + uWSGI启动Python应用服务
参考并感谢:Erick-LONG 和 自强学堂
uWSGI是一个Web应用服务器,它具有应用服务器,代理,进程管理及应用监控等功能。它支持WSGI协议,同时它也支持自有的uWSGI协议,该协议据说性能非常高,而且内存占用率低,为mod_wsgi的一半左右,我没有实测过。它还支持多应用的管理及应用的性能监控。虽然uWSGI本身就可以直接用来当Web服务器,但一般建议将其作为应用服务器配合Nginx一起使用,这样可以更好的发挥Nginx在Web端的强大功能。本文我们就来介绍如何搭建uWSGI+Ngnix环境来运行Python应用。
安装uWSGI
(env27)wfq@ubuntu:~$ sudo env27/bin/pip install uwsgi
不过查看安装日志稍微有些小问题不知后续时候使用是否会有影响:
Could not find .egg-info directory in install record for uwsgi
uwsgi部分安装日志:
############## end of uWSGI configuration #############
total build time: 41 seconds
*** uWSGI is ready, launch it with /home/wfq/python27/bin/uwsgi ***
Could not find .egg-info directory in install record for uwsgi
Successfully installed uwsgi
Cleaning up...
(env27)wfq@ubuntu:~$
WSGI应用demo:uwsgi_test.py
写个Hello World的WSGI应用,并保存在uwsgi_test.py文件中:
wfq@ubuntu:~/ops$ pwd
/home/wfq/ops
wfq@ubuntu:~/ops$ ls
8888 9999 asb db.sqlite3 django_wsgi.py django_wsgi.pyc logs manage.py myapp.log nohup.out ops test tools uwsgi_socket.ini uwsgi_test.py
wfq@ubuntu:~/ops$ cat uwsgi_test.py
def application(environ, start_response):
status = '200 OK'
output = 'Hello World!'
response_headers = [('Content-type', 'text/plain'),
('Content-Length', str(len(output)))]
start_response(status, response_headers)
return [output]
wfq@ubuntu:~/ops$
在uWSGI中运行它,执行命令:
wfq@ubuntu:~/ops$ /home/wfq/python27/bin/uwsgi --http :9999 --wsgi-file uwsgi_test.py &
检查启动状态:
wfq@ubuntu:~/ops$
wfq@ubuntu:~/ops$ ps -ef | grep 9999
wfq 31035 30441 0 19:54 pts/0 00:00:00 /home/wfq/python27/bin/uwsgi --http :9999 --wsgi-file uwsgi_test.py
wfq 31036 31035 0 19:54 pts/0 00:00:00 /home/wfq/python27/bin/uwsgi --http :9999 --wsgi-file uwsgi_test.py
wfq 31039 30441 0 19:55 pts/0 00:00:00 grep --color=auto 9999
wfq@ubuntu:~/ops$
访问检查成功,so 奈斯
命令说明:
上面的命令中”- -http”参数指定了HTTP监听地址和端口,”- -wsgi-file”参数指定了WSGI应用程序入口,uWSGI会自动搜寻名为”application”的应用对象并调用它。
更进一步,uWSGI可以支持多进程和多线程的方式启动应用,也可以监控应用的运行状态。我们将启动的命令改为:
wfq@ubuntu:~/ops$ /home/wfq/python27/bin/uwsgi --http :9999 --wsgi-file uwsgi_test.py --master --processes 2 --threads 2 --stats 127.0.0.1:8999
执行它后,uWSGI将启动2个应用进程,每个进程有2个线程,和一个master主进程(监控其他进程状态,如果有进程死了,则重启)。同时,你可以访问”127.0.0.1:8999″来获取JSON格式的应用运行信息(我检查失败,暂时略过),uWSGI还提供了工具命令”uwsgitop”来像top一样监控应用运行状态,你可以用pip来安装它。
wfq@ubuntu:~/nginx/logs$ ps -ef | grep 9999
wfq 31063 30441 0 20:00 pts/0 00:00:00 /home/wfq/python27/bin/uwsgi --http :9999 --wsgi-file uwsgi_test.py --master --processes 2 --threads 2 --stats 127.0.0.1:8999
wfq 31064 31063 0 20:00 pts/0 00:00:00 /home/wfq/python27/bin/uwsgi --http :9999 --wsgi-file uwsgi_test.py --master --processes 2 --threads 2 --stats 127.0.0.1:8999
wfq 31065 31063 0 20:00 pts/0 00:00:00 /home/wfq/python27/bin/uwsgi --http :9999 --wsgi-file uwsgi_test.py --master --processes 2 --threads 2 --stats 127.0.0.1:8999
wfq 31066 31063 0 20:00 pts/0 00:00:00 /home/wfq/python27/bin/uwsgi --http :9999 --wsgi-file uwsgi_test.py --master --processes 2 --threads 2 --stats 127.0.0.1:8999
wfq 31070 30476 0 20:00 pts/2 00:00:00 grep --color=auto 9999
wfq@ubuntu:~/nginx/logs$
上面的命令参数太多了,我们可以将参数写在配置文件里,启动uWSGI时指定配置文件即可。配置文件可以是键值对的格式,也可以是XML,YAML格式,这里我们使用键值对的格式。
ini配置文件方式启动
让我们创建一个配置文件”uwsgi_socket.ini”:
其中module为:/home/wfq/ops/django_wsgi.py
即chdir目录下的django_wsgi.py配置文件
wfq@ubuntu:~/ops$ pwd
/home/wfq/ops
wfq@ubuntu:~/ops$ cat uwsgi_socket.ini
[uwsgi]
socket=:8888
chdir=/home/wfq/ops
pythonpath=/home/wfq/python27/bin/python
module=django_wsgi
processes=2
daemonize=/home/wfq/ops/logs/uwsgi.log
wfq@ubuntu:~/ops$
启动命令简化为:
wfq@ubuntu:~$ sudo /home/wfq/python27/bin/uwsgi /home/wfq/ops/uwsgi_socket.ini
[uWSGI] getting INI configuration from /home/wfq/ops/uwsgi_socket.ini
wfq@ubuntu:~$
wfq@ubuntu:~$ ps -ef | grep uwsgi
root 31916 1 7 14:09 ? 00:00:00 /home/wfq/python27/bin/uwsgi /home/wfq/ops/uwsgi_socket.ini
root 31921 31916 0 14:09 ? 00:00:00 /home/wfq/python27/bin/uwsgi /home/wfq/ops/uwsgi_socket.ini
wfq 31923 31777 0 14:09 pts/2 00:00:00 grep --color=auto uwsgi
wfq@ubuntu:~$ sudo lsof -i:8888
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
uwsgi 31916 root 3u IPv4 145255 0t0 TCP *:8888 (LISTEN)
uwsgi 31921 root 3u IPv4 145255 0t0 TCP *:8888 (LISTEN)
uwsgi 31921 root 5u IPv4 147033 0t0 TCP 192.168.174.132:8888->192.168.174.1:62511 (ESTABLISHED)
wfq@ubuntu:~$
wfq@ubuntu:~$ ps -ef | grep 31921
root 31921 31916 0 14:09 ? 00:00:00 /home/wfq/python27/bin/uwsgi /home/wfq/ops/uwsgi_socket.ini
wfq 32036 31777 0 14:30 pts/2 00:00:00 grep --color=auto 31921
wfq@ubuntu:~$
配置nginx
在/home/wfq/nginx/conf中copy一份ops.conf,主要配置如下,配置表明Nginx会将收到的所有请求都转发到”192.168.174.132:8888″端口,即uWSGI服务器上。
server {
listen 8000;
server_name 192.168.174.132;
access_log /home/wfq/nginx/logs/ops.access.log;
location / {
include uwsgi_params;
uwsgi_pass 192.168.174.132:8888;
}
}
启动nginx的:
~/nginx/sbin/nginx -c ~/nginx/conf/ops.conf
wfq@ubuntu:~$ ps -ef | grep nginx
root 32006 1 0 14:23 ? 00:00:00 nginx: master process /home/wfq/nginx/sbin/nginx -c /home/wfq/nginx/conf/ops.conf
nobody 32007 32006 0 14:23 ? 00:00:00 nginx: worker process
wfq 32009 31777 0 14:23 pts/2 00:00:00 grep --color=auto nginx
wfq@ubuntu:~$
wfq@ubuntu:~$ lsof -i:8000
wfq@ubuntu:~$ sudo lsof -i:8000
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nginx 32006 root 8u IPv4 146740 0t0 TCP *:8000 (LISTEN)
nginx 32007 nobody 8u IPv4 146740 0t0 TCP *:8000 (LISTEN)
wfq@ubuntu:~$
浏览器访问8000端口
至此,配置记录完成,昨晚开始写的中途本本没电,中断后今天继续完成,可能会有遗漏不足的地方。