Python生产环境部署(fastcgi,uwsgi)
Python部署web开发程序的几种方法
fastcgi ,通过flup模块来支持,在nginx里对应的配置指令是 fastcgi_pass
http,nginx使用proxy_pass转发,这个要求后端appplication必须内置一个能处理高并发的http server,在python的web框架当中,只能选择tornado.
uwsgi,包括4部分组成:
- uwsgi协议
- web server内置支持协议模块
- application服务器协议支持模块
- 进程控制程序
nginx从0.8.4开始内置支持uwsgi协议,uwsgi协议非常简单,一个4个字节header+一个body,body可以是很多协议的包,比如说http,cgi等(通过header里面字段标示)。
uwsgi的特点在于自带的进程控制程序.它是用c语言编写,使用natvie函数,其实和spawn-fcgi/php-fpm类似。所以uwsgi可以支持多种应用框架,包括(python,lua,ruby,erlang,go)等等
mod_python,这是apache内置的模块,很严重的依赖于mod_python编译使用的python版本,和apache配套使用,不推荐
cgi,这个太old,不推荐,而且nginx不支持cgi方式,只能用lighttpd或者apache
spawn-fcgi,这个是fastcgi多进程管理程序,lighttpd安装包附带的,和 flup效果一样,区别是flup是 python代码级引入,spawn-fcgi是外部程序。spawn-fcgi用途很广,可以支持任意语言开发的代码,php,python,perl,只要你代码实现了fastcgi接口,它都可以帮你管理你的进程
scgi,全名是Simple Common Gateway Interface,也是cgi的替代版本,scgi协议很简单,我觉得和fastcgi差不多,只是没有怎么推广开来,nginx对应的配置指令是scgi_pass,你想用就用,flup也支持。
Gunicorn,和uwsgi类似的工具,从rails的部署工具(Unicorn)移植过来的。但是它使用的协议是 WSGI,全称是Python Web Server Gateway Interface ,这是python2.5时定义的官方标准(PEP 333 ),根红苗正,而且部署比较简单,http://gunicorn.org/ 上有详细教程
mod_wsgi,apache的一个module,也是支持WSGI协议,https://code.google.com/p/modwsgi/
uwsgi
安装uwsgi
pip install uwsgi
配置uwsgi
uwsgi 有多种配置可用:
1,ini
2,xml
3,json
4,yaml
配置示例
$ cat etc/uwsgi.ini
[uwsgi]
socket = 127.0.0.1:9005
chdir = /Users/suoning/python_project/trunk/
wsgi-file = main.py
processes = 4
stats = 127.0.0.1:9000
daemonize = /tmp/uwsgiServer.log
pidfile = /tmp/uwsgi.pid
vacuum = true
log-maxsize = 50000000
disable-logging = true
callable = app
$
配置参数详解:
常用选项:
socket : 地址和端口号,例如:socket = 127.0.0.1:50000
processes : 开启的进程数量
workers : 开启的进程数量,等同于processes(官网的说法是spawn the specified number of workers / processes)
chdir : 指定运行目录(chdir to specified directory before apps loading)
wsgi-file : 载入wsgi-file(load .wsgi file)
stats : 在指定的地址上,开启状态服务(enable the stats server on the specified address)
threads : 运行线程。由于GIL的存在,我觉得这个真心没啥用。(run each worker in prethreaded mode with the specified number of threads)
master : 允许主进程存在(enable master process)
daemonize : 使进程在后台运行,并将日志打到指定的日志文件或者udp服务器(daemonize uWSGI)。实际上最常用的,还是把运行记录输出到一个本地文件上。
log-maxsize :以固定的文件大小(单位KB),切割日志文件。 例如:log-maxsize = 50000000 就是50M一个日志文件。
pidfile : 指定pid文件的位置,记录主进程的pid号。
vacuum : 当服务器退出的时候自动清理环境,删除unix socket文件和pid文件(try to remove all of the generated file/sockets)
disable-logging : 不记录请求信息的日志。只记录错误以及uWSGI内部消息到日志中。如果不开启这项,那么你的日志中会大量出现这种记录:
[pid: 347|app: 0|req: 106/367] 117.116.122.172 () {52 vars in 961 bytes} [Thu Jul 7 19:20:56 2016] POST /post => generated 65 bytes in 6 msecs (HTTP/1.1 200) 2 headers in 88 bytes (1 switches on core 0)
配置nginx
$ cat etc/nginx/servers/pan.conf server {
listen 80;
server_name localhost; location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:9005;
} location /webstatic/ {
expires 7d;
add_header Cache-Control public;
alias /Users/suoning/probject/python_project/webstatic/trunk/;
} } $
$ nginx -t
nginx: the configuration file /usr/local/etc/nginx/nginx.conf syntax is ok
nginx: configuration file /usr/local/etc/nginx/nginx.conf test is successful
$
$ nginx -s reload
$
配置application
flask 示例
...
app = Flask('pan')
... if __name__ == '__main__':
# app.run(host='0.0.0.0', port=5000)
app.run() # 注意:变量app对应uwsgi配置文件uwsgi.ini中 callable = app
启动uwsgi
$
$ uwsgi --ini /usr/local/etc/uwsgi.ini
[uWSGI] getting INI configuration from /usr/local/etc/uwsgi.ini
$
$ ps -ef|grep uwsgi
501 11428 1 0 11:40下午 ?? 0:01.23 uwsgi --ini /usr/local/etc/uwsgi.ini
501 11432 11428 0 11:40下午 ?? 0:00.00 uwsgi --ini /usr/local/etc/uwsgi.ini
501 11433 11428 0 11:40下午 ?? 0:00.00 uwsgi --ini /usr/local/etc/uwsgi.ini
501 11434 11428 0 11:40下午 ?? 0:00.00 uwsgi --ini /usr/local/etc/uwsgi.ini
501 11435 11428 0 11:40下午 ?? 0:00.00 uwsgi --ini /usr/local/etc/uwsgi.ini
501 11440 69240 0 11:40下午 ttys000 0:00.00 grep uwsgi
$
$ lsof -i tcp:9000
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
uwsgi 11428 suoning 28u IPv4 0x5583e11534d24e73 0t0 TCP localhost:cslistener (LISTEN)
$
$ lsof -i tcp:9005
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
uwsgi 11428 suoning 6u IPv4 0x5583e11535699e73 0t0 TCP localhost:9005 (LISTEN)
uwsgi 11432 suoning 6u IPv4 0x5583e11535699e73 0t0 TCP localhost:9005 (LISTEN)
uwsgi 11433 suoning 6u IPv4 0x5583e11535699e73 0t0 TCP localhost:9005 (LISTEN)
uwsgi 11434 suoning 6u IPv4 0x5583e11535699e73 0t0 TCP localhost:9005 (LISTEN)
uwsgi 11435 suoning 6u IPv4 0x5583e11535699e73 0t0 TCP localhost:9005 (LISTEN)
$
FCGI
参考:http://webpy.org/cookbook/fastcgi-nginx
配置Nginx
$ cat etc/nginx/servers/pan.conf server {
listen 80;
server_name localhost; error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
} location / {
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_script_name;
fastcgi_pass 127.0.0.1:9005;
} location /webstatic/ {
expires 7d;
add_header Cache-Control public;
alias /Users/suoning/probject/python_project/webstatic/trunk/;
} } $
配置application
简单示例
from flup.server.fcgi import WSGIServer
from pan import app WSGIServer(
app,
bindAddress=(host, port),
maxThreads=threads
).run()
生产环境示例
#!/usr/bin/env python
# -*- coding: utf-8 -*-
__author__ = 'suoning' import sys
import argparse
from flup.server.fcgi import WSGIServer
from lib.daemon import Daemon
from pan import app APP_NAME = 'pan_platform'
APP_INST_NAME = '' parser = argparse.ArgumentParser(description=u'Run an pan FastCGI server')
parser.add_argument('command', type=str,
help=u'command [start|stop|restart]',
choices=['start', 'stop', 'restart'])
parser.add_argument('-p', '--port', type=int,
help=u'port of this server', required=True)
parser.add_argument('-t', '--threads', type=int, default=50,
help=u'max number of threads')
parser.add_argument('-host', '--host', default='0.0.0.0',
help=u'Listen to the main clause') class panPlatformDaemon(Daemon):
def run(self):
# 运行服务
try:
WSGIServer(
app,
bindAddress=(args.host, args.port),
maxThreads=args.threads,
umask=0111
).run()
except:
sys.stderr.write('oops') def gen_pidfile(port):
return '/var/run/%s_%s_%d.pid' % (APP_NAME, APP_INST_NAME, port) if __name__ == '__main__':
args = parser.parse_args()
daemon = panPlatformDaemon(gen_pidfile(args.port))
if 'start' == args.command:
daemon.start()
elif 'stop' == args.command:
daemon.stop()
elif 'restart' == args.command:
daemon.restart()
else:
print "Unknown command"
sys.exit(2)
sys.exit(0)
fastcgi协议和http协议在代码部署中的的优劣对比
fastcgi虽然是二进制协议,相对于http协议,并不节省资源。二进制协议,只能节省数字的表达,比如 1234567,用字符串表示需要7个Byte,用数字就是4个Byte,而字符串到哪里都一样
fastcgi在传输数据的时候,为了兼容cgi协议,还要带上一堆cgi的环境变量,所以和http协议相比,用fastcgi传输数据并不省,反而多一些
fastcgi 唯一的优点是,它是长连接的,用户并发1000个request,fastcgi可能就用10个 链接转发给后端的appplication,如果用http协议,那来多少给多少,会向后端appplication 发起1000个请求
http代理转发方式,在面对超高并发的情况下会出问题,因为,tcp协议栈当中,port是int16整型 你本地新建一个connect,需要消耗一个端口,最多能到65536。外部并发几十万个请求,port池耗干,你的服务器只能拒绝响应了
CGI, FCGI, SCGI, WSGI 区别
WIKI Links:
Python生产环境部署(fastcgi,uwsgi)的更多相关文章
- 第四百零二节,Django+Xadmin打造上线标准的在线教育平台—生产环境部署,uwsgi安装和启动,nginx的安装与启动,uwsgi与nginx的配置文件+虚拟主机配置
第四百零二节,Django+Xadmin打造上线标准的在线教育平台—生产环境部署,uwsgi安装和启动,nginx的安装与启动,uwsgi与nginx的配置文件+虚拟主机配置 软件版本 uwsgi- ...
- python生产环境部署
Python部署web开发程序的几种方法 fastcgi ,通过flup模块来支持,在nginx里对应的配置指令是 fastcgi_pass http,nginx使用proxy_pass转发,这个要求 ...
- 生产环境使用Nginx+uwsgi部署Django
在本地运行django应用相对来说还是挺方便的,使用自带的runserver启动即可.如果在生产环境部署django,就要多考虑一些问题了.比如静态文件处理,安全,效率等等 在网上找到了不错的部署的教 ...
- Django + Uwsgi + Nginx 的生产环境部署
使用runserver可以使我们的django项目很便捷的在本地运行起来,但这只能在局域网内访问,如果在生产环境部署django,就要多考虑一些问题了.比如静态文件处理,安全,效率等等,本篇文章总结归 ...
- ubuntu Django + Uwsgi + Nginx 的生产环境部署
一.概述 使用runserver可以使我们的django项目很便捷的在本地运行起来,但这只能在局域网内访问,如果在生产环境部署django,就要多考虑一些问题了.比如静态文件处理,安全,效率等等,本篇 ...
- 10: Django + Uwsgi + Nginx 的生产环境部署
1.1 一些重要概念 1.Web协议介绍 Web协议出现顺序: CGI -> FCGI -> WSGI -> uwsgi 1. CGI: 最早的协议 2. FCGI: 比CGI快 ...
- Django + Uwsgi + Nginx 的生产环境部署实战
目录 Django + Uwsgi + Nginx 的生产环境部署实战 安装Uwsgi 一.使用命令来启动django项目 二.使用配置文件来启动我们的Django项目 安装Nginx 配置Nginx ...
- Django+Nginx+uWSGI生产环境部署
生产环境中的数据流 参考文档: wsgi详解:https://blog.csdn.net/li_101357/article/details/52748323 wsgi协议介绍(萌新版):https: ...
- 第四百零一节,Django+Xadmin打造上线标准的在线教育平台—生产环境部署virtualenv虚拟环境安装,与Python虚拟环境批量安装模块
第四百零一节,Django+Xadmin打造上线标准的在线教育平台—生产环境部署virtualenv虚拟环境安装,与Python虚拟环境批量安装模块 virtualenv简介 1.安装virtuale ...
随机推荐
- win10环境下jdk1.8+Android Developer Tools Build: v22.3.0-887826的问题
最进换了新电脑,配置开发环境,最新的android studio 要求jdk1.8,所以想都没想就下载1.8. 之后为了一个原来的老项目,得使用adt,遂装之,遇到一下问题 1.ADT新建项目src下 ...
- shiro权限控制
1.1 简介 Apache Shiro是Java的一个安全框架.目前,使用Apache Shiro的人越来越多,因为它相当简单,对比Spring Security,可能没有Spring Securi ...
- fis-plus 学习笔记
学习了一些fls-plus前端集成的东西:学的很皮毛,很多都是对官网的解释希望与大家分享,并能得到大家的指正. 参考文档:http://oak.baidu.com/fis-plus/document. ...
- jquery.zclip.js 不起作用
最近有用到复制的这个功能,选用jQuery的插件,正常使用的时候,没有任何问题: $('#copy_mobile_watch_address').zclip({ path: '/dist/plugin ...
- shell 之时间戳
vim 1.sh #/bin/bash##by cc read -p "Please input yourtime:" timea=$timeif [ $a != 0 ] then ...
- 隐式的处理SOAPHeader消息
先用一下比较基础的隐式方式处理我的SOAPHeader消息,注意的是QName的使用,代码如下: public static void main(String[] args) { try { //创建 ...
- require.js 源码解读——配置默认上下文
首先,我们先来简单说一下,require.js的原理: 1.载入模块 2.通过模块名解析出模块信息,以及计算出URL 3.通过创建SCRIPT的形式把模块加载到页面中. 4.判断被加载的脚本,如 ...
- 新人报道~cnblogs
我的名字:杨先生 我的英文名:Allen 和你们一样,是一名程序猿,专业技能 C#.前端小块.
- try{} catch(…){} 讨论(转)
以前都是用try{} catch(…){}来捕获C++中一些意想不到的异常, 今天看了Winhack的帖子才知道,这种方法在VC中其实是靠不住的.例如下面的代码: .try .{ .BYTE* pch ...
- 老李分享:接电话扩展之uiautomator 2
主要的类就是上面的PhoneReceiver广播接收者.来电的时候,我们记录下电话号码,等该来电挂断以后,立即回拨给对方.配置文件如下: <?xml version="1.0" ...