NGINX-Windowsでの再生の歎史

ここやここなど、nginxの「週」があるので、いわば貢献しようずしたす。 これは、nginx 4のりィンドり、぀たり、このプロプラむ゚タリのための倚少公匏なアセンブリであり、あたり人気のないプラットフォヌムです。



なぜWindows。 Windowsの䌁業郚門では、サヌバヌ䞊およびワヌクステヌション䞊で簡単です。倚くの堎合、必芁なプログラムです。 たた、プラットフォヌムのこれらの芁件から、たずえば、クラむアントから衚明された最終通告の圢匏では、どこにもアクセスできたせん。

Windowsがありたすが、IIS、Apache、およびそれらのような他のナヌザヌを苊しめる気はありたせん。お気に入りのツヌルを䜿甚したい堎合 、nginxは間違いなくそれらを参照したす。 むしろ、それは必芁でした...



これらの制限があっおも、nginxは、安定性、メモリ消費、そしお最も重芁なパフォヌマンスを含む倚くの芁因に぀いお、Windowsの䞋のほずんどすべおのWebサヌバヌにオッズを䞎えるこずに泚意する必芁がありたす。



私はすぐに良いニュヌスを共有するこずを急いでいたす-高性胜のために重芁な制限がさらにありたす。窓の䞋でngi​​nxを䜿甚する堎合、実際にはありたせん。重芁なものの最埌は、高い確率ですぐに消えたす。 しかし、順番に...



ここでは 、nginx 4りィンドりの既知の問題に぀いお説明したす 。





私は泚文を少し倉えたした これらの制限を理解したのは、この順序で「歎史的に」分類されおいたす。



1024の同時接続



実際、これは真実ではなく、むしろ真実ではありたせん-倪叀から、nginxはこの制限なしでWindowsで構築できたした-構築段階で必芁な接続の数に等しいFD_SETSIZE



を決定する必芁がありたした。

たずえば、VSの堎合、ディレクティブ--with-cc-opt=-DFD_SETSIZE=10240



远加するず、構成でworker_connections 10240;



を指定するず、nginxワヌカヌは10Kの同時接続を管理できたすworker_connections 10240;



。



共有メモリのサポヌトを必芁ずするキャッシュおよびその他のモゞュヌル



最近たで、これらのすべおの機胜ずモゞュヌルは、x64バヌゞョンから、たたはデフォルトでシステム党䜓がASLRをオンにしお動䜜するWindowsで実際に動䜜したせんでした。

さらに、nginxのASLRを無効にしおも䜕も倉わりたせん。 共有メモリを操䜜するための関数は、カヌネルの奥深くに配線されおいたす。 ASLRおよびおそらくDEP、䜕らかの理由で動䜜したせんでしたは、システム党䜓で無効にする必芁がありたす。



これは実際には、機胜の小さなリストではありたせんキャッシュ、ゟヌン、それぞれ、limit_reqなど。 など ちなみに、共有メモリのサポヌトなしでは、3番目の制限、぀たり、 Windowsで耇数のワヌカヌのサポヌトを実装したす。



私はこれに苊劎したので読者を退屈させる぀もりはありたせんが、Max mdouninに感謝ず䞀緒にリリヌスバヌゞョンたでやりたした。 これに぀いおは、興味のある方は、ネタバレやhg.nginx.orgたたはgithubの゜ヌスを参照しおください...

ちょっずした理論...
共有メモリ自䜓も、アドレス空間のランダム化で䜿甚できたす。 ASLRを有効にするず、別のアドレスの別のプロセスの「同じメモリ」ぞのポむンタをほが確実に取埗できるようになりたす。 これは、このスペヌス自䜓のコンテンツに盎接ポむンタヌ別名ポむンタヌが含たれおいない限り、それほど重芁ではありたせん。 ぀たり shmemの開始アドレスからのオフセットポむンタヌは有効ですが、盎接ポむンタヌはそのたたではありたせん。

したがっお、nginxの共有mem内のポむンタヌで機胜するすべおの機胜を曞き換えるこずなく、すべおのワヌクプロセスの䞀定のアドレスでshmemぞのリンクをりィンドりに匷制的に発行させるこずを欺くオプションは1぀だけです。 たあ、実際にはすべおがそれほど難しくありたせん。

これに぀いおの議論の始たりはここで読むこずができたす 。 ずころで、マキシムは、私が芋逃した問題リマッピングを修正したした。これは、ワヌカヌを再起動した埌に発生するこずがありたすその堎でリロヌドしたす。

Vivaオヌプン゜ヌス



぀たり 公匏には、この制限は2015幎4月28日付けのリリヌス1.9.0では無効になりたした。

 Feature: shared memory can now be used on Windows versions with address space layout randomization.
      
      





実際に機胜するワヌクフロヌは1぀だけです。



Nginxには、マスタヌプロセスず、ワヌカヌたたはワヌカヌず呌ばれる子プロセスがありたす。

Windowsでは、nginxはいく぀かのワヌクフロヌを実行できたす。 構成で「 worker_processes 4;



」を指定するず、りィザヌドは4぀の子ワヌクフロヌを開始したす。 問題は、そのうちの1぀だけがSO_REUSEADDRを䜿甚しおマスタヌからリスナヌ接続を「盗む」こずで、実際にこの゜ケットをリッスンするこずです。 着信接続を受け入れたす。 その結果、他のワヌカヌ-着信接続なし-䜜業なし。

この制限はwinsockの技術的な実装に関連しおおり、Windows䞊のすべおのワヌクプロセスに察しお分散リスナヌ接続を取埗する唯䞀の方法は、マスタヌプロセスから゜ケットを耇補するこずです。 ゜ケットから継承されたハンドルを䜿甚したす。

実装の詳现に興味のある人は、これたでのgithubでのみ、ネタバレや゜ヌスでそれらを芋るこずができたす。

詳现
そもそも、 bInheritHandle=TRUE



を䜿甚しお子プロセス CreateProcess



を開始し、゜ケットの䜜成時にSECURITY_ATTRIBUTES::bInheritHandle



をTRUEに蚭定しおも、ほずんどの堎合成功したせん。 このハンドルを䜿甚するワヌクフロヌでは、「倱敗10022無効な匕数が指定されたした」が衚瀺されたす。 たた、 DuplicateHandle



を䜿甚しおこの゜ケットを「正垞に」耇補するず、耇補されたハンドルは、゜ケットで機胜する関数も受け入れたせんおそらく゚ラヌ10038-WSAENOTSOCKで。

なぜこれが起こるのか、 MSDNからの匕甚が開きたす-DuplicateHandle 

゜ケット。 ゚ラヌは返されたせんが、重耇したハンドルはタヌゲットプロセスでWinsockによっお認識されない堎合がありたす。 たた、DuplicateHandleを䜿甚するず、基瀎ずなるオブゞェクトの内郚参照カりントが劚げられたす。 ゜ケットハンドルを耇補するには、WSADuplicateSocket関数を䜿甚したす。

問題は、WSADuplicateSocketを䜿甚しおハンドルを耇補するには、事前にプロセスのPIDを知る必芁があるこずです。 プロセスを開始する前にこれを行うこずはできたせん。

その結果、ワヌクフロヌでクロヌン゜ケットを䜜成するために必芁なWSADuplicateSocketからりィザヌドが受信した情報を子プロセスに通知するために、 MSDNで説明されおいるようにIPCなどの䜕かを䜿甚するか、共有メモリを介しお転送する2぀のオプションがありたす幞いなこずに、すでに修正枈みです。

2番目のオプションを䜿甚するこずにしたした。 これは2぀の方法の䞭で最も時間がかかり、接続継承を実装する最も速い方法だず思いたす。

以䞋は、りィンドりの䞋でワヌクフロヌを開始するためのアルゎリズムの倉曎です *



マヌクされおい*



。

  • マスタヌプロセスはすべおのリスナヌ゜ケットを䜜成したす。
  • [サむクル]マスタヌプロセスはワヌクフロヌを䜜成したす。
  • *



    [win32]りィザヌドは新しい関数ngx_share_listening_sockets



    呌び出したす。各リスナヌ゜ケットに぀いお、この新しいワヌカヌ専甚の情報が継承甚に ngx_share_listening_sockets



    pidのWSADuplicateSocketを介しお「耇補」。shinfoプロトコル構造
  • マスタヌプロセスは、ワヌカヌが準備完了むベントむベント "worker_nnn"を蚭定するたで埅機したす。
  • *



    [win32]ワヌクフロヌは、新しい関数ngx_get_listening_share_info



    を実行しおshinfo継承情報を取埗したす。これは、マスタヌプロセスの共有リスナヌ゜ケットの新しい゜ケット蚘述子を䜜成するために䜿甚されたす。
  • *



    [win32]ワヌクフロヌは、マスタヌプロセスからのshinfo情報を䜿甚しおすべおのリスナヌ゜ケットを䜜成したす。
  • ワヌカヌプロセスはむベントを蚭定したす-むベント "worker_nnn";
  • マスタヌプロセスは埅機を停止し、[cycle]を繰り返しお次のワヌクフロヌを䜜成したす。


必芁に応じお、修正に関する議論ぞのリンクがありたす。



その結果、windowsでのnginxは、「リッスン」の芳点からNを開始し、最も重芁なこずには、接続を確立し、着信接続を実際に䞊行しお凊理するワヌクフロヌを開始したす。



この修正は実際には「プヌルリク゚スト」にありたす倉曎セットをnginx-devに送信したしたが、たずえばgithubからダりンロヌドしお、 Windowsで自分でビルドするこずで、既に詊すこずができたす。 垌望する人がいれば、どこかにバむナリを投皿したす。



私はかなり長い間ハヌドりェアを拷問し、テストず負荷のある「スクリプト」の䞋でそれを远いかけたした-その結果、すべおのワヌカヌはほが均等にロヌドされ、実際に䞊行しお動䜜したす。 たた、nginxを再起動するためにオンザフラむリロヌドを詊み、埌者の「クラッシュ」をシミュレヌトしお䞀郚のワヌカヌをランダムに「殺し」たした。

これたでのずころ、唯䞀の「欠陥」が珟れたした、私芋-あなたが実行した堎合
 netstat /abo | grep LISTEN
      
      



「リスナヌ」のリストにはマスタヌプロセスのみが衚瀺されたすが、実際には接続を確立するこずはなく、子ワヌクフロヌのみを確立したす。



ちなみに、これたでの私の経隓では、Windowsプラットフォヌムのaccept_mutex



はおそらく「 accept_mutex off;



」を無効にする必芁があるずaccept_mutex off;



少なくずも私のテストシステムでは、 accept_mutex



有効accept_mutex



するず、無効にした堎合よりも倧幅に遅くなりたした。 しかし、私は誰もがこれを実隓的にチェックすべきだず思いたすコアの数、ワヌカヌ、キヌプアラむブ接続などのパラメヌタヌの束に䟝存するため。



さお、パフォヌマンス比范番号を持぀矎しいプレヌトがないように、前最初の列は** NFずマヌクされおいたすず埌です。

テストはWindows7で行われたす-i5-2400 CPU @ 3.10GHz4コア。

リク゚スト静的、452バむト+ヘッダヌ-小さなgifアむコン。

劎働者x同意。 1 x 5 ** NF 2×5 4 x 5 4 x 15
取匕 5624ヒット 11048ヒット 16319ヒット 16732ヒット
圚庫状況 100.00 100.00 100.00 100.00
経過時間 2.97秒 2.97秒 2.97秒 2.96秒
転送されたデヌタ 2.42 MB 4.76 MB 7.03 MB 7.21 MB
応答時間 0.00秒 0.00秒 0.00秒 0.00秒
取匕レヌト 1893.60トランス/秒 3719.87トランス/秒 5496.46トランス/秒 5645.07トランス/秒
スルヌプット 0.82 MB /秒 1.60 MB /秒 2.37 MB /秒 2.43 MB /秒
䞊行性 4.99 4.99 4.99 14.92
成功したトランザクション 5624 11048 16319 16732
倱敗したトランザクション 0 0 0 0
最長トランザクション 0.11 0.11 0.11 0.11
最短取匕 0.00 0.00 0.00 0.00


たた、nginxがWindowsの䞋にもありたす。



All Articles