質問: webサーバーはどのようにしてipアドレスを「リッスン」し、割り込みまたはポーリングを行いますか? webサーバーの下位の詳細を理解しようとしています。サーバー(apacheなど)が新しいリクエストを継続的にポーリングしているか、または何らかの割り込みシステムで機能しているかどうかを考えています。それが割り込みである場合、何がその割り込みを引き起こしているのですか、それはネットワークカードドライバですか?
回答: 「下位」の詳細はかなりたくさんあります。まず、カーネルにはプロセスのリストがあり、常に、これらのプロセスの一部は実行中、一部は実行されていないことを考慮してください。カーネルは、実行中の各プロセスにcpu時間の一部を許可し、それを中断して次のプロセスに移動します。実行可能なプロセスがない場合、カーネルはおそらく [〜#〜] hlt [〜#〜] のような命令をcpuに発行し、ハードウェア割り込みが発生するまでcpuを一時停止します。サーバーのどこかに システムコール があり、「何かをしてくれ」と言っています。これを行う方法には、大きく分けて2つのカテゴリがあります。 apacheの場合、apacheが以前に開いたソケットで accept を呼び出し、おそらくポート80でリッスンします。カーネルは接続試行のキューを維持し、そのキューに時間 tcp syn が受信されます。カーネルがどのようにtcp= synを受信したか)を知るかは、デバイスドライバーによって異なります。多くのnicの場合、ネットワークデータを受信したときにハードウェア割り込みが発生する可能性があります。acceptは、カーネルに次の接続開始を私に返すように要求します。キューが空でなければ、acceptはただちに戻ります。キューが空の場合、プロセス(apache)は実行中のプロセスのリストから削除されます。後で接続が開始されると、プロセスが再開されます。これは「ブロッキング」と呼ばれます。これは、それを呼び出すプロセスにとって、accept()が、結果が出るまで返らない関数のように見えるためです。その間、プロセスは他に何もできません。acceptが返されると、apacheは誰かが接続を開始しようとしていることを認識します。次に fork を呼び出して、apacheプロセスを2つの同一のプロセスに分割します。これらのプロセスの1つはhttp要求の処理を続行し、他のプロセスは次の接続を取得するために再度acceptを呼び出します。したがって、常にacceptを呼び出してサブプロセスを生成する以外に何もしないマスタープロセスがあり、リクエストごとに1つのサブプロセスがあります。これは単純化です。これをプロセスの代わりにスレッドで実行することも可能です。また、事前にforkを実行して、リクエストを受信したときにすぐに実行できるワーカープロセスを用意して、起動のオーバーヘッドを減らすこともできます。 apacheの構成方法に応じて、apacheはこれらのいずれかを実行します。これは、その方法の最初の大まかなカテゴリであり、システムはacceptやreadとwriteは、ソケットで動作し、何か返されるまでプロセスを一時停止します。それを行う他の広範な方法は、非ブロッキングまたはイベントベースまたは 非同期io と呼ばれます。これは select または epoll のようなシステムコールで実装されます。これらはそれぞれ同じことを行います。ソケット(または一般的にはファイル記述子)のリストと、ソケットで何をしたいかを指定し、カーネルがそれらのいずれかを実行する準備ができるまでブロックします。このモデルを使用すると、カーネルに(epollを使用して)、「ポート80に新しい接続があるか、開いているこれらの9471のその他の接続のいずれかで読み取る新しいデータがある場合に通知する」と伝えることができます。 epollは、これらのいずれかの準備ができるまでブロックし、それからそれを行います。その後、繰り返します。 acceptやreadやwriteのようなシステムコールはブロックしません。これは、コールするたびにepollが準備ができていることを通知するためです。 dブロックする理由はありません。また、ソケットまたはファイルを開いたときに、それらを非ブロックモードで使用するように指定しているため、これらの呼び出しは ewouldblock で失敗しますブロッキング。このモデルの利点は、必要なプロセスが1つだけであることです。つまり、リクエストごとにスタックとカーネル構造を割り当てる必要はありません。 nginx と haproxy がこのモデルを使用しているため、同様のハードウェアでapacheよりもはるかに多くの接続を処理できる大きな理由です。