¸üÐÂʱ¼ä:2016Äê09ÔÂ13ÈÕ17ʱ35·Ö À´Ô´:ÀÖÓã²¥¿Í ä¯ÀÀ´ÎÊý:
Òý£ºDjangoÊÇPythonÖÚ¶àweb¿ò¼ÜÖÐÌṩ¹¦ÄÜ×îÈ«×î·á¸»µÄÒ»¸ö£¬ÄÇôÎÒÃÇÔÚʵ¼ÊÓ¦ÓÃÖÐͨ³£Ôõôȥ²¿ÊðDjangoÄØ?ÏÂÃæÎÒÃǾÍÀ´¿´Ò»¿´DjangoµÄ²¿Êð·½°¸ÓÐÄÄЩ¡£
1. Python web ³ÌÐòµÄ²¿Êð·½·¨£º
DjangoÊDzÉÓÃpythonдµÄweb¿ò¼Ü£¬ÎÒÃÇÏÈÀ´¿´ÏÂpythonµÄweb³ÌÐòµÄ9ÖÖ²¿Êð·½·¨£º
· mod_python£¬ÕâÊÇapacheÄÚÖõÄÄ£¿é£¬ºÜÑÏÖØµÄÒÀÀµÓÚmod_python±àÒëʹÓõÄpython°æ±¾£¬ºÍapacheÅäÌ×ʹÓ㬲»ÍƼö;
· cgi£¬Õâ¸öÌ«old£¬²»ÍƼö£¬¶øÇÒnginx²»Ö§³Öcgi·½Ê½£¬Ö»ÄÜÓÃlighttpd»òÕßapache;
· fastcgi £¬Õâ¸öÊÇĿǰÁ÷ÐÐ×î¹ãµÄ×ö·¨£¬Í¨¹ýflupÄ£¿éÀ´Ö§³ÖµÄ£¬ÔÚnginxÀï¶ÔÓ¦µÄÅäÖÃÖ¸ÁîÊÇ fastcgi_pass;
· 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Ò²Ö§³Ö;
· http£¬nginxʹÓÃproxy_passת·¢,Õâ¸öÒªÇóºó¶Ëapplication±ØÐëÄÚÖÃÒ»¸öÄÜ´¦Àí¸ß²¢·¢µÄhttp server£¬ÔÚpythonµÄweb¿ò¼Üµ±ÖУ¬Ö»ÄÜÑ¡Ôñtornado;
python³ÌÐòԱϲ»¶·¢Ã÷ÂÖ×Ó£¬tornado³ýÁËÊÇÒ»¸öweb frameworkÖ®Í⣬Ëü»¹¿ÉÒÔµ¥¶ÀÌṩ¸ßÐÔÄÜhttp server£¬ËùÒÔ£¬Èç¹ûÄã²ÉÓÃÆäËûpython¿ò¼Üд´úÂ룬±ÈÈç˵bottle£¬Ò²Ò»Ñù¿ÉÒÔͨ¹ýimport tornado À´Æô¶¯Ò»¸ö¸ßÐÔÄܵÄhttp server£¬Í¬ÑùµÄ¿ÉÒÔ²ÉÓÃhttpÐÒéºÍnginxÒ»ÆðÀ´²¿Êð¡£À©Õ¹¿ªÀ´£¬python°üÀïÃæÄÜ´¦Àí¸ß²¢·¢µÄhttp server»¹Óкܶ࣬±ÈÈç˵gevent£¬Ò²¿ÉÒÔ±»ÆäËû¿ò¼ÜÒýÓÃÀ´Ö§³Öhttp·½Ê½²¿Êð¡£
· uwsgi£¬°üÀ¨4²¿·Ö×é³É£º
o uwsgiÐÒé
o web serverÄÚÖÃÖ§³ÖÐÒéÄ£¿é
o application·þÎñÆ÷ÐÒéÖ§³ÖÄ£¿é
o ½ø³Ì¿ØÖƳÌÐò
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)µÈµÈ
· Gunicorn£¬ºÍuwsgiÀàËÆµÄ¹¤¾ß£¬´ÓrailsµÄ²¿Ê𹤾ß(Unicorn)ÒÆÖ²¹ýÀ´µÄ¡£µ«ÊÇËüʹÓõÄÐÒéÊÇ WSGI£¬È«³ÆÊÇPython Web Server Gateway Interface £¬ÕâÊÇpython2.5ʱ¶¨ÒåµÄ¹Ù·½±ê×¼(PEP 333 )£¬¸ùºìÃçÕý£¬¶øÇÒ²¿Êð±È½Ï¼òµ¥;
· mod_wsgi£¬apacheµÄÒ»¸ömodule£¬Ò²ÊÇÖ§³ÖWSGIÐÒé,https://code.google.com/p/modwsgi/
2. Nginx + uWSGI + Django
ÏÈÀ´³ÎÇ弸¸ö¸ÅÄ
WSGI: WSGIÊÇÒ»ÖÖWeb·þÎñÆ÷Íø¹Ø½Ó¿Ú¡£ËüÊÇÒ»¸öWeb·þÎñÆ÷(Èçnginx)ÓëÓ¦Ó÷þÎñÆ÷(ÈçuWSGI·þÎñÆ÷)ͨÐŵÄÒ»Öֹ淶¡£
uwsgi: uwsgiͬWSGIÒ»ÑùÊÇÒ»ÖÖͨÐÅÐÒ飬¶øuWSGIÊÇʵÏÖÁËuwsgiºÍWSGIÁ½ÖÖÐÒéµÄWeb·þÎñÆ÷¡£
uwsgiÐÒéÊÇÒ»¸öuWSGI·þÎñÆ÷×ÔÓеÄÐÒ飬ËüÓÃÓÚ¶¨Òå´«ÊäÐÅÏ¢µÄÀàÐÍ(type of information)£¬Ã¿Ò»¸öuwsgi packetǰ4byteΪ´«ÊäÐÅÏ¢ÀàÐÍÃèÊö£¬ËüÓëWSGIÏà±ÈÊÇÁ½Ñù¶«Î÷¡£
uWSGI: uWSGIÊÇÒ»¸öWeb·þÎñÆ÷£¬ËüʵÏÖÁËWSGIÐÒé¡¢uwsgi¡¢httpµÈÐÒé¡£ NginxÖÐHttpUwsgiModuleµÄ×÷ÓÃÊÇÓëuWSGI·þÎñÆ÷½øÐн»»»¡£
uWSGIµÄÖ÷ÒªÌØµãÈçÏ£º
³¬¿ìµÄÐÔÄÜ
µÍÄÚ´æÕ¼ÓÃ(ʵ²âΪapache2µÄmod_wsgiµÄÒ»°ë×óÓÒ)
¶àapp¹ÜÀí
Ï꾡µÄÈÕÖ¾¹¦ÄÜ(¿ÉÒÔÓÃÀ´·ÖÎöappÐÔÄÜºÍÆ¿¾±)
¸ß¶È¿É¶¨ÖÆ(ÄÚ´æ´óСÏÞÖÆ£¬·þÎñÒ»¶¨´ÎÊýºóÖØÆôµÈ)
ÓÉÓÚuWSGIÓÐ×ÅÉÏÊöÓŵ㣬ͨ³£²ÉÓÃNginx + uWSGI + DjangoÀ´²¿Êð£¬ÐÔÄÜÓëÎȶ¨ÐÔ¶¼²»´í¡£
²¿Êð·½·¨£º
1 °²×°uwsgi
pip install uwsgi
2 дÅäÖÃÎļþ yourfile.ini (ÎļþÃû¿É×Ô¶¨Òå)
[uwsgi]
socket = 127.0.0.1:3031
chdir = /home/foobar/myproject/
wsgi-file = myproject/wsgi.py
processes = 4
threads = 2
master= True
pidfile = yourfile.pid
daemonize = yourfile.log
3 Ö´ÐÐ uwsgi yourfile.ini
4 nginx ÅäÖÃ
location / {
uwsgi_pass 127.0.0.1:8630;
include uwsgi_params;
}
3. Nginx + Tornado + Django
TornadoÊÇÒ»¸öÒì²½web¿ò¼ÜºÍ·þÎñÆ÷£¬ËùÒÔÔÚ¿ª·¢³¤ÂÖѯµÄchatÖ®ÀàÓ¦Ó÷dz£µÄºÏÊÊ£¬µ«ÊÇÆäʵ±¾ÉíÒ²ÊÇÒ»¸ö¸ßÐÔÄܵÄhttp·þÎñÆ÷£¬Ò²¿ÉÒÔ×÷Ϊһ¸öWSGIServer¡£ËùÒÔ¼´Ê¹ÍøÕ¾Ã»ÓÐʹÓÃTornadoµÄ¿ò¼Ü£¬¶øÊÇÓÃÁËweb.py»òÕßÊÇDjangoÀ´¿ª·¢£¬ TornadoÒÀÈ»¿ÉÒÔÓÃÀ´¼ÓËÙÍøÕ¾¡£Ê¹ÓÃTornadoÀ´´úÌæfastCGI¿ÉÒÔ´ó·ùÌá¸ßÐÔÄÜ£¬ÇÒ¿ÉÒÔ³ÐÔØµÄ²¢·¢ÄÜÁ¦Ò²ÓÐÁ˳ɱ¶µÄÌá¸ß¡£
²¿Êð·½·¨£º
²ÉÓÃNginxͨ¹ýupstreamÀ´·´Ïò´úÀíµ½N¸öTornadoµÄ·þÎñÆ÷ʵÀýÉϵIJ¿Êð·½Ê½¡£
Setp1£º°²×°supervisord
ÓÉÓÚTornado²¢Ã»ÓÐ×ÔÉíÌṩDaemonµÄÄÜÁ¦£¬ËùÒÔÐèÒªÓÃÒ»¸ö·þÎñ¹ÜÀí¹¤¾ßÀ´¹ÜÀíTornadoµÄ½ø³Ì£¬supervisordÊÇÓÃPythonʵÏÖµÄÒ»¿î·Ç³£ÊµÓõĽø³Ì¹ÜÀí¹¤¾ß¡£¿ÉÒԺܷ½±ãµÄ¹ÜÀíN¹ý½ø³Ì£¬ÇÒÖ§³Ö½ø³Ì·Ö×é¡£Supervisord¿ÉÒÔͨ¹ýsudo easy_install supervisor°²×°£¬µ±È»Ò²¿ÉÒÔͨ¹ýSupervisord¹ÙÍøÏÂÔØºósetup.py install°²×°¡£
Step2: ¸øDjangoµÄÕ¾µãÔö¼ÓÒ»¸öTornadoµÄ·þÎñÆ÷Îļþ(±ÈÈçserv.py)
´´½¨Ò»¸öÎļþServ.pyÔÚDjangoÕ¾µãµÄ¸ùĿ¼(Django 1.4ÖÐÓ¦¸Ã·Åµ½ºÍurls.pyͬһ¼¶Ä¿Â¼)£¬ÄÚÈÝÈçÏ£º
import os
import sys
from tornado.options import options, define, parse_command_line
import django.core.handlers.wsgi
import tornado.httpserver
import tornado.ioloop
import tornado.web
import tornado.wsgi
HERE = os.path.dirname(os.path.abspath(file_))
sys.path.append(_HERE)
sys.path.append(os.path.join(_HERE, '..'))
sys.path.append(os.path.join(_HERE, '../contrib'))
os.environ['DJANGO_SETTINGS_MODULE'] = "settings"
def main(port):
wsgi_app = tornado.wsgi.WSGIContainer(
django.core.handlers.wsgi.WSGIHandler())
tornado_app = tornado.web.Application(
[('.*', tornado.web.FallbackHandler, dict(fallback=wsgi_app)),
])
server = tornado.httpserver.HTTPServer(tornado_app)
server.listen(port)
tornado.ioloop.IOLoop.instance().start()
if __name__ == 'main':
main(int(sys.argv[1]))
ÎÒÕâÀïͨ¹ýµÚÒ»¸ö²ÎÊýÀ´Ö¸¶¨Tornado·þÎñ¼àÌýµÄ¶Ë¿Ú¡£ÕâÑù±È½ÏÁé»î£¬ÕâµãÎÒÃÇÔÚºóÃæµÄ²½Öè»áÓõ½¡£Õâ¸öʱºòÎÒÃÇ¿ÉÒÔͨ¹ýpython Serv.py 8000Õâ¸öÃüÁîÀ´Æô¶¯·þÎñÆ÷
Step3: ÅäÖÃSupervisord
µÚÒ»²½°²×°µÄSupervisord»¹Ã»ÓÐÅäÖã¬ËùÒÔÎÒÃÇÐèÒªÏÈ´´½¨Ò»¸öÅäÖÃÎļþµÄÑù°å¡£ÔÚrootȨÏÞÏÂÖ´ÐÐecho_supervisord_conf > /etc/supervisord.confÕâ¸öʱºòÔÚ/etc/´´½¨ÁËÅäÖÃÎļþ£¬ÓÃvim´ò¿ªÕâ¸öÎļþ£¬ÔÚÅäÖÃÎļþµÄƨ¹ÉºóÃæ¼ÓÉÏÒÔÏÂÕâÒ»¶Î
[program:web]
command=python /var/www/site/Serv.py 80%(process_num)02d
process_name=%(program_name)s_%(process_num)02d
umask=022
startsecs=0
stopwaitsecs=0
redirect_stderr=true
stdout_logfile=/tmp/codoon.log
numprocs=4
numprocs_start=1
Õâ¸öÅäÖûáÆô¶¯4¸öTornadoµÄ·þÎñ½ø³Ì·Ö±ð¼àÌý 8001,8002,8003,8004 ÕâËĸö¶Ë¿Ú
commandÕâÒ»ÐÐÊÇÒªÖ´ÐеÄÃüÁÕâÀïÊÇÓà python /var/www/site/Serv.py ¶Ë¿ÚºÅÀ´Æô¶¯TornadoµÄ·þÎñ½ø³Ì 80%(process_num)02d µÄÓÃ;ÊÇͨ¹ý½ø³Ì±àºÅÀ´Éú³É¶Ë¿ÚºÅ¡£ÏÂÃæµÄprocess_nameÕâ¸ö²ÎÊýÒ²»áÓõ½¡£ÕâÀïÒªÖ¸¶¨µÄÎļþÃû¾ÍÊÇÉÏÒ»²½ÎÒÃÇ´´½¨ÄǸöServ.pyÎļþ
process_nameÊǽø³ÌµÄÃû×Ö£¬ÓÉÓÚÕâÀïÒªÆô¶¯4¸ö½ø³Ì£¬ËùÒÔÒªÓÃprocess_numÀ´Çø·Ö
umaskÊdzÌÐòÖ´ÐеÄȨÏÞ²ÎÊý
startsecsÕâ¸ö²ÎÊýÊdzÌÐòÆô¶¯µÄµÈ´ýʱ¼ä
stopwaitsecsÕâ¸ö²ÎÊýÊdzÌÐòÍ£Ö¹µÄµÈ´ýʱ¼ä
redirect_stderrÕâ¸ö²ÎÊý½«´íÎóÁ÷ÖØ¶¨Ïòµ½stdµÄÁ÷Êä³ö£¬ÕâÑù¿ÉÒÔʡȥһ¸öÈÕÖ¾ÎļþµÄÅäÖ㬵±È»Ò²¿ÉÒÔ²»ÓÃÕâ¸ö²ÎÊý·Ö¿ªÅäÖÃÈÕÖ¾Îļþ
stdout_logfile Õâ¸ö²ÎÊýÊÇSTDÁ÷Êä³öÈÕÖ¾ÎļþµÄ·¾¶£¬Tornado»áÊä³öËùÓеÄÇëÇóºÍ´íÎóÐÅÏ¢£¬Í¨¹ýÕâ¸ö¿ÉÒÔͳһ×öÈÕÖ¾´¦Àí£¬·Ö¸ôʲôµÄ£¬ÔÚ³ÌÐòÀï¾ÍÖ»ÐèÒªprintµ½stdÁ÷¾ÍÐÐÁË¡£
numprocs Õâ¸ö²ÎÊýÖ¸¶¨Á˽ø³ÌµÄÊýÁ¿£¬ÕâÀïÊÇ4£¬±íÃ÷ÒªÆô¶¯4¸öTornado½ø³Ì
numprocs_start Õâ¸ö²ÎÊýÖ¸¶¨Á˽ø³ÌºÅµÄÆðʼ±àºÅ£¬ÕâÀïÊÇ1£¬ÕâÑùÇ°ÃæµÄcommandºÍprocess_nameÀïµÄ%(process_num)02d²¿·Ö¾Í»áÔÚÖ´ÐеÄʱºò±»Ì滻Ϊ01~05µÄ×Ö·û´®
ÅäÖÃÐÞ¸ÄÍê³Éºó:wq±£´æÍ˳ö£¬Ö´ÐУº
supervisorctl reload
ÖØÐ¼ÓÔØÅäÖúó£¬ÕâЩ½ø³Ì¾ÍÆô¶¯ÆðÀ´ÁË
Step4£ºÐÞ¸ÄÅäÖÃNginx
Ê×ÏÈÕÒµ½ÔÚvhostĿ¼ÀïÄãµÄÕ¾µãÅäÖÃÎļþ£¬´ò¿ªºó£¬ÔÚÍ·ÉÏÔö¼ÓupstreamµÄÄÚÈÝ
upstream frontends {
server 127.0.0.1:8001;
server 127.0.0.1:8002;
server 127.0.0.1:8003;
server 127.0.0.1:8004;
}
È»ºóÔÚServerÅäÖýÚÀïÕÒµ½
location / { Õâ¸öÅäÖýÚ
ÒÔǰÊÇÓõÄFastCGI£¬ËùÒÔÀïÃæµÄÅäÖÿÉÄÜÊÇÕâÑù×ÓµÄ
host and port to fastcgi server
fastcgi_pass 127.0.0.1:8081;
fastcgi_param PATH_INFO $fastcgi_script_name;
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_pass_header Authorization;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
fastcgi_intercept_errors off;
°ÑÕâЩͳͳɾµô£¬±ä³ÉÁËÕâÑù
location / {
}
ÔÚ{}ÖмÓÈëupstreamµÄÅäÖ㬱ä³ÉÈçÏÂÑù×Ó
location / {
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_pass http://frontends;
proxy_next_upstream error;
}
±£´æÅäÖÃÎļþºóÖ´ÐÐ ÈÃnginxÖØÆôµÄÖ¸Áî nginx -s reload(×¢Òâ nginxÎļþÔÚ²»Í¬·¢ÐаæÖÐλÖÃÓвî±ð)
±±¾©Ð£Çø