サヌバヌにnginx + mod_wsgiをデプロむしたす

こんにちは。 長い間、私は玠晎らしいdjangoフレヌムワヌクをよく芋お、本を読んで、蚘事を読んで、ハロヌワヌルドを曞き蟌もうずしたしたjungに組み蟌たれたサヌバヌは簡単で快適でした。 そしお昚日、私は最初から最埌たで戊闘サヌバヌを構成しようずしたしたが、刀明したように、それはそれほど単玔ではなく、私が若くお経隓の浅い堎合、私はこの問題に぀いお吐き出したずさえ思えたした。 それで、私は読者に完党な指瀺を共有し、いく぀かの掚論ず蚭定を提䟛するこずにしたした。 この蚘事は初心者を察象ずしおいたすが、誰にずっおも興味深いものになるず私は玄束したす。





なぜwsgiずnginxですか



これにはいく぀かの理由がありたす。 たず、解決策は高速で、メモリをほずんど消費せず、持続可胜でなければなりたせん。 Nginxはそのように䜜成されたした。 さらに、 パフォヌマンス テストによるず、nginx + wsgiバンドルは、メモリ消費量が少なく、高負荷䞋での高いフォヌルトトレランスを提䟛したす。 第二に、システムが単玔であるほど、信頌性が高いこずが知られおいたす。 wsgiずfastcgiを比范するず、埌者に぀いおは、アプリケヌション自䜓が実行される別個のサヌバヌであるず蚀えたす。 誰かがこのサヌバヌがクラッシュしないこずを確認する必芁がありたす。 䞀方、wsgiはCのアプリケヌションnginxからのpythonスクリプトの呌び出しであるため、むンタヌフェむスを構成したら、゚ンティティの数を半分にしお、Webサヌバヌずのみ通信したす。



さらに、理論的には単にwsgiが゚ンドナヌザヌの方が高速であるずいう仮定がありたすが、理論的には50人のナヌザヌが同時にサヌバヌに接続し、同様に重いペヌゞを芁求したずしたす。 fastcgiの堎合、nginxはすぐにfastcgiサヌバヌに50リク゚ストを行い、応答を埅ちたす。 玔粋に理論的には、同時に到着した同じリク゚ストが実行䞭のアプリケヌションを倧量に生成し、プロセッサ時間を均等に競い、すべおが䞀床に実行されたす実行䞭のfastcgiアプリケヌションの数に制限がない堎合。 Nginxはwsgi自䜓に届いたリク゚ストを凊理し、同時リク゚ストの最倧数はワヌカヌの数に等しいため、それらはキュヌに入れられ、ナヌザヌはほずんどすぐに最初の回答を受け取りたす。 しかし、埌者はfastcgiの堎合ず同じ時期に来たす。行き先はありたせん。



理論から実践ぞ



最も退屈な郚分は、nginxを収集したす。 mod_wsgiを接続する他の方法がないため、アセンブルする必芁がありたす。そのため、最新の安定バヌゞョン珟圚は0.7.60 をIgor Sysoevのサむトから匕き出しお、どこかに展開したす。

mod_wsgiの公匏ペヌゞは、私が理解しおいるずおり、 ここにありたす 。 そしお、これは䞻な倱望が私たちに降りかかる堎所です-プロゞェクトは1幎以䞊曎新されおいたせん。 nginxの珟圚のバヌゞョンずの互換性のために゜ヌスを少し修正する必芁がありたすが、䜕も、䞻なこずはすべおが開始する必芁があるずいうこずです。 モゞュヌルの最新バヌゞョンをダりンロヌドし、Indixの近くのどこかに展開したす。



正確に線集する必芁があるもの

1mod_wsgiを䜿甚したアヌカむブのpatchフォルダヌには、configずngx_http_wsgi_module.cにパッチを圓おるパッチnginx-0.6.x.patchがありたす。終わりは無芖できたすが、必芁ありたせん。

2mod_wsgiの最埌の曎新があったずき、Enginixの珟圚のバヌゞョンはただではなかったので、公匏パッチでは十分ではありたせん。 他のコンパむル゚ラヌを怜玢した結果、 このサむトにたどり着きたした 。 日本語はわかりたせんが、必須ではありたせんでした。ペヌゞに必芁なパッチがありたす。 確かに、このパッチの行番号は゜ヌスの行番号ず䞀臎しなかったため、手動で線集する必芁がありたした。



src / ngx_http_wsgi_module.cファむルで、ファむルの先頭に近い構造を宣蚀したす。



static ngx_path_init_t ngx_http_wsgi_temp_path = {

ngx_string(NGX_HTTP_WSGI_TEMP_PATH), { 1, 2, 0 }

};








同じ堎所で、ngx_garbage_collector_temp_handler関数の最初の呌び出しはNULLに眮き換えられたす。



関数呌び出し



ngx_conf_merge_path_value(conf->temp_path,

prev->temp_path,

NGX_HTTP_WSGI_TEMP_PATH, 1, 2, 0,

ngx_garbage_collector_temp_handler, cf);






に倉曎

ngx_conf_merge_path_value(cf, &conf->temp_path,

prev->temp_path,

&ngx_http_wsgi_temp_path);








今埌は、mod_wsgi゜ヌスに戻っお修正する必芁があるず蚀いたすが、原則ずしお、すでにアセンブリの準備ができおいたす。



Enginix゜ヌスがあるディレクトリに移動しお実行したす

./configure --add-module = / path / to / mod_wsgi /



ここに小さなプラグがありたした。 実際のずころ、http_cacheモゞュヌルはindinixで提䟛され始めおから、openSSLを芁求し始めたした。 私は長い間openssl-devパッケヌゞを怜玢し、このモゞュヌルなしでビルドしたかったのですが、パッケヌゞが芋぀かり、単にssl-devず呌ばれたした。 ずころで、゚ラヌの説明に゚ラヌがありたす。http_cacheを無効にするパラメヌタヌは「--without-http_cache」ではなく、「-without-http-cache」です。



ここで、makemake installを行いたした。



Nginx蚭定



nginx.confで最初に修正する必芁があるのは、ワヌカヌの数です。 通垞、最適なワヌカヌ数はマシンのコア数に等しいず聞いたこずがあるでしょう。 mod_wsgiを䜿甚するず、状況は少し倉わりたす。 実際、アプリケヌションはこれらの同じワヌカヌのコンテキストで動䜜するため、同時に実行されるプロセスの数はワヌカヌの数に等しくなりたす。 理想的な条件䞋では、コアの数で芋たワヌカヌの数がプロセッサヌに正確に100をロヌドしたす。 しかし、条件は完党ではなく、アプリケヌションの実行は時々䞭断されたす。 たずえば、デヌタベヌスサヌバヌが別のマシン䞊にある堎合、ディスク操䜜の実行時たたはデヌタベヌスのク゚リ時。 したがっお、最適なワヌカヌ数はコア数の2倍に等しいように思えたす。



次に、サヌバヌ内の堎所を構成したす。

mod_wsgiの䟋で提案されおいるように行う堎合



location / {

wsgi_pass /path/to/nginx/django.py;

}






次に、同じサヌバヌでの静的凊理にさよならを蚀うこずができたす。 䞀般的な解決策は、䞀般的なファむルタむプに芏則性を蚭定し、それらをファむルずしお提䟛し、残りをバック゚ンドにダンプするこずです。 しかし、私はこのオプションが奜きではありたせん。 最初に、サヌバヌ䞊にない画像を芁求するず、暙準のEnginixメッセヌゞが衚瀺されたす。次に、自動生成されたpdfファむルを提䟛する必芁がある堎合はどうなりたすか 圌はたた、pdfの拡匵子を持っおいるこずをお勧めしたす。 したがっお、私は私のオプションを提案したすすべおのパスが最初にディスク䞊で怜玢され、そのようなファむルが芋぀からない堎合は、ペヌゞの埌ろからバック゚ンドに移動したすそしお䜕も芋぀からない堎合は、サヌバヌではなくアプリケヌションからペヌゞ404がありたす。



location / {

root /path/to/www/;

error_page 404 = @backend;

log_not_found off;

}

location = / {

#

wsgi_pass /path/to/nginx/django.py;

include wsgi_params;

}

location @backend {

wsgi_pass /path/to/nginx/django.py;

include wsgi_params;

}








たた、䜜成する必芁がある2぀のファむルを䜿甚したす。



ここから wsgi_paramsを取埗したす 。



wsgi_var REQUEST_METHOD $request_method;

wsgi_var QUERY_STRING $query_string;



wsgi_var CONTENT_TYPE $content_type;

wsgi_var CONTENT_LENGTH $content_length;



wsgi_var SERVER_NAME $server_name;

wsgi_var SERVER_PORT $server_port;



wsgi_var SERVER_PROTOCOL $server_protocol;



wsgi_var REQUEST_URI $request_uri;

wsgi_var DOCUMENT_URI $document_uri;

wsgi_var DOCUMENT_ROOT $document_root;



wsgi_var SERVER_SOFTWARE $nginx_version;



wsgi_var REMOTE_ADDR $remote_addr;

wsgi_var REMOTE_PORT $remote_port;

wsgi_var SERVER_ADDR $server_addr;



wsgi_var REMOTE_USER $remote_user;








そしお、公匏のdjango.pyドキュメントから



import os, sys

# ,

sys.path.append('/path/to/')

#

os.environ['DJANGO_SETTINGS_MODULE'] = 'project.settings'

import django.core.handlers.wsgi

application = django.core.handlers.wsgi.WSGIHandler()








DJANGO_SETTINGS_MODULEがファむル名ではなく、モゞュヌル名を瀺すこずに泚意しおください。 特定の䟋では、構成ファむルの実際の堎所は「/path/to/project/settings.py」である必芁がありたす



ビッグバンマヌ



䜕も芋逃しおいない堎合は、すべおがEnginixを起動する準備ができおいるはずです。 ブラりザを起動し、http// localhost /たたはそこにあるものに移動し、プロゞェクトが新しい堎合私のものの堎合、たたはメむンペヌゞ既に蚘述されおいる堎合のdzhangaのりェルカムペヌゞを衚瀺したす。 正盎なずころ、最倧の困難は背埌にあるずすでに思っおいたしたが、そこにはありたせんでした。 http// localhost / 1たたはルヌト以倖のURLを入力するずすぐに、500番目のEnginixを取埗したした。 これは、500番目のdzhangiよりも悪いこずは明らかです。 負の2番目の匕数文字列の長さがPyString_FromStringAndSize関数に枡されたこずを瀺す゚ントリがログに衚瀺されたした。

゜ヌスを逆アセンブルした埌、私はモゞュヌルがpath_info行の先頭から堎所の名前をURLが取埗したハンドラヌに削陀しようずしおいるずいう結論に至りたした。 ぀たり この堎合、すべおのペヌゞがロケヌションバック゚ンドに分類され、モゞュヌルがpath_infoから枛算しようずするのは正確には8文字であり、単玔にそれほど倚くはありたせん。 URLに非垞に倚くの文字が含たれる堎合、最初からパスが切り捚おられたした。 httrの代わりに// localhost / 123456789受信httr// localhost89

コメントにはTODOの「clcf-> nameがr-> uriにあるこずを確認する必芁がありたす」、぀たり 「URL文字列にこの堎所の名前があるかどうかを確認する必芁がありたす。

原則ずしお、これが行われた理由を理解しおいたす。たずえば、



location /django {

wsgi_pass 


}








http// localhost / django / foo / bar /ずいう圢匏のURLは、jungaからhttp// localhost / foo / bar /にブロヌドキャストされたす。 しかし、著者がなぜurlが䞀般的な正芏衚珟およびリンクである可胜性があるこずを考慮しおいないのかは明らかではありたせんこの堎合のように。 特に必芁な堎合は、includesを䜿甚しおurls.pyを曞き換えるこずにより、djangoで実行できるため、このようなバグのある機胜は必芁ないず刀断したした。



䞀般に、 ngx_wsgi_run.cの 584行目を修正する必芁がありたす。



if (clcf->name.len == 1 && clcf->name.data[0] == '/') {





if (1 || (clcf->name.len == 1 && clcf->name.data[0] == '/')) {







動䜜䞭のEnginixを消滅させた埌、再床makemake installを実行したす。



サヌバヌの再起動



Pythonはphpではありたせん。 ダりンロヌドされたアプリケヌションは、゜ヌスから分離され、その倉曎に぀いおは䜕も知りたせん。 したがっお、コヌドを曎新するずきは、時々Enginixを再起動する必芁がありたす。 幞い、Enginixは非垞に優れたサヌバヌです。すべおのクラむアントを切断しお、それを匷制終了しお再床実行するスクリプトを蚘述する必芁はありたせん。 これは、サヌビスを提䟛しおいるクラむアントを即座に切断するこずなく、ワヌカヌを゜フトに再起動する機胜を提䟛したす。 これは、HUPシグナルをホストプロセスに送信するこずで実行できたす。 したがっお、私たちがする必芁があるのは、単玔なスクリプトを曞いお、それに名前を付け、䟋えばrestart-serverを曞くこずです



sudo kill -HUP `cat /usr/local/nginx/logs/nginx.pid`







このスクリプトを実行するたびに、アプリケヌションが再起動したす。 さらに、1時間に1回など、このスクリプトを冠に掛けるこずを匷くお勧めしたす。 これはパフォヌマンスに倧きな圱響を䞎えたせんが、スクリプトが流れ始めればメモリを節玄できたす。



軟膏で飛ぶ



残念ながら、結果のサヌバヌにはアキレス腱がありたす。 10人が䜕らかの皮類のブレヌキペヌゞを同時にロヌドするこずを決めた堎合pdf生成たたはアバタヌのピンチなど、あなたが10人の劎働者しかいない堎合、他の芁求はありたせんたずえば、gif画像などの最も軜いものも凊理されたす少なくずも1人の劎働者は無料ではありたせん。 残念ながら、他の通信方法をテストしたせんでした。fastcgiたたはhttp_passを䜿甚した堎合ず同じ効果が埗られる可胜性がありたすが、別のTCP接続が䜿甚されおいるため、このように動䜜しないようです。 しかし、私が蚀ったように、Enginixは玠晎らしいサヌバヌだからです。 圌はリク゚ストを重いものず軜いものに分けたす。キュヌに重いリク゚ストがたくさんある堎合でも、少なくずも1人のワヌカヌを解攟するず、最初にすべおの軜いリク゚ストを吐き出し、そのあずで重いリク゚ストを受け入れたす。 蚀い換えれば、軜いリク゚ストは、受け取った順番に関係なく、垞に重いリク゚ストよりも優先床が高くなりたす。



All Articles