2017-03-22 2 views
1

Linuxで動作し、TCPを使用したプッシュベースのメッセージングサービスを実装するC++で書かれたサーバープログラムがあります。プッシュアプ​​ローチのために、私は約100万人を予定していますが、より多くの時間をかけてオープンにしなければならない同時接続が数多くあります。ほとんどの場合、これらの接続は時折ハートビートでアイドル状態になり、転送は通常、同時に多数のバーストで発生します。多くのファイル記述子でselect()を使用する外部コード

大量のソケットを多重化するためにepollを使用しています。RLIMIT_NOFILEを変更することで、実際には大量のソケットではうまく動作します。

私の問題は、同じプログラム内で他のタイプの接続、特にFastCGI(FastCGI SDKのlibfcgiを使用)を使用して、内部ファイル記述子にselect()を使用するHTTP要求を受け入れることです。これは、これらのファイルディスクリプタは、1024(FD_SETSIZE)より大きくなったときに問題となる、プログラムのepoll一部は1024

下にFD番号のほとんどを使用している場合、私は何を最善の方法を思ったんだけど起こるにバインドされていますこれを処理することができます。

select()を使用する外部コードをすべて変更して、代わりにpoll()を使用するだけですか?

は多分以下のものがselect()ベースのコードのために予約されているように、1024を超えるだけのファイル記述子を使用するために私のepollベースのコード(特にaccept()コール)を強制する方法はありますか?

FD_SETSIZEの値を何とか増やすことができると私は理解していますが、実際の解決策ではなくハックとして私を襲ってしまいます。

答えて

1

これらのことを独自のプロセスに移動し、独自のファイル記述子を取得することをお勧めします。私がお勧めするのは、単一のTCP接続で多数のTCP接続を多重化するプロトコルがあることです。サーバーは個々のクライアントではなくマルチプレクサと通信します。マルチプレクサは同じマシンまたは異なるマシン上で動作することができ、数万のクライアント接続を処理することができ、サーバへの接続を1つだけにします。

大きな利点の1つは、サーバーマシンが多数のTCP接続状態を処理する必要がないことです。パケットの破棄、再送信、重複パケット、不正なSYN、低速リンクなどのインターネット迷惑メールを処理する必要はありません。各クライアントに送信バッファを持つ必要はありませんが、クライアントのバッファリングを行うことができる高速でクリーンなマルチプレクサと話をするだけです。

これが多すぎる場合や何らかの理由で不可能な場合は、dup2を使用してファイル記述子の番号を高い番号のディスクリプタに変更することができます。マルチプレクサの使用を強くお勧めします。処理しようとしている接続の数が単一のプロセスでは大きすぎます。

+0

サーバーはすでに複数のインスタンスとして実行されており、クライアントは使用可能なサーバーのいずれかをランダムに選択するか、負荷に基づいて選択します。別の多重化レイヤーを追加することは可能かもしれませんが、コードをもっと大きく変更する必要がありますので、私はこのアプローチを今のところ望んでいません。 dup2は有望ですね。今では 'dup2'に渡された' newfd'が他の場所で使われていないことを確認するだけです。なぜなら、 'dup2'がランダムなfdsを閉じたくないからです。 –

+0

"処理しようとしている接続の数が単一のプロセスから行うには大きすぎます"。本当にそうですか?ほとんどの場合、それらはアイドル状態にあり、何かが転送されると、実際にはそれらのすべて(またはそのグループ)と同じデータになります。私は、TCP再送信が多くのクライアントにとって問題になるかもしれないと思う(私は主に、同じ物理マシン上のサーバとクライアント、異なるVMで動作しているクライアントでテストを行っている)が、サーバがすべての要求に答えるのに数秒かかる場合私のユースケースのために十分速い時間です。 –

+0

@AlemariusNexus起動時に、設定された制限と同じくらい多くのファイル記述子を開きます(おそらく '/ dev/null'を開いて)。 1,024未満のものを閉じます。 'dup2'にファイルディスクリプタのプールがあります。ファイル記述子が終了した時点でファイル記述子を閉じるのではなく、予備のファイル記述子の1つを 'dup2 'にしてください。 –

関連する問題