1

select()を使用して設計されたWebサーバーがあり、先週まで実際には多くの負荷が発生することはなく、500〜1000 conn/sの負荷で常に正常に動作していました。ただし、最近、はるかに高い負荷(およびスパイク)が発生し始め、ソケットハンドル> FD_SETSIZEを確認した後、select()がおかしくなるという問題が発生しました。これは、FD_SETにFD_SETSIZEを超えるものがある場合、繰り返しタイムアウトした後、selectが壊れないループに入るとサーバーをフリーズさせるだけです。ポーリング(またはepoll)に切り替えるオプションは現在ありません。選択に固執する必要があります。今のところ修正した方法は、listenキューを増やし、accept()の代わりに新しい接続が> = FD_SETSIZEであることがわかり、リスニングソケットのselect()に戻ったときに、新しい接続の受け入れを停止することです。これは、OSがファイルハンドルをリサイクルし、常に利用可能な最小のものを提供しようとするために機能します。しかし、欠点は、ソケットハンドルが> = FD_SETSIZEの場合、accept()を呼び出すときに一部の接続にRSTを送信することになることです。これは、サーバーの実行を維持し、接続の低下が約5%であるため、今のところ許容できます。それらの接続を切断せずにそれを行うことができる方法はありますか?使用済みのハンドルや複雑すぎるものをすべて数えたくありません。偽のソケットを作成し、そのハンドルをチェックして、acceptを呼び出す前に閉じると、次に何のハンドルが提供されるかをかなり正確に見積もることができます。これは、サーバーの実行を維持し、接続の低下が約5%であるため、今のところ許容できます。それらの接続を切断せずにそれを行うことができる方法はありますか?使用済みのハンドルや複雑すぎるものをすべて数えたくありません。偽のソケットを作成し、そのハンドルをチェックして、acceptを呼び出す前に閉じると、次に何のハンドルが提供されるかをかなり正確に見積もることができます。これは、サーバーの実行を維持し、接続の低下が約5%であるため、今のところ許容できます。それらの接続を切断せずにそれを行うことができる方法はありますか?使用済みのハンドルや複雑すぎるものをすべて数えたくありません。偽のソケットを作成し、そのハンドルをチェックして、acceptを呼び出す前に閉じると、次に何のハンドルが提供されるかをかなり正確に見積もることができます。

while(max_conn_to_accept--){
SOCKET a_s = accept(..);
if(a_s >= FD_SETSIZE){
    close(a_s);
    return;
}
4

1 に答える 1

1

上げるだけFD_SETSIZEです。-DFD_SETSIZE=16384コンパイラのコマンド ラインで指定します。

あなたのバージョンは十分に新しいので、他に問題はないと思います。ヘッダー ファイルでエラーが発生した場合は、1 ~ 2 行の調整が必要になる場合があります。

たとえば、次のようなものが表示された場合:

#undef __FD_SETSIZE
#define __FD_SETSIZE    1024

これを次のように変更します。

#undef __FD_SETSIZE
#ifndef FD_SETSIZE
#define __FD_SETSIZE    1024
#else
#define __FD_SETSIZE    FD_SETSIZE
#endif

または、次のように表示される場合:

#define FD_SETSIZE      1024

次のように変更します。

#ifndef FD_SETSIZE
#define FD_SETSIZE      1024
#endif

しかし、繰り返しますが、何も変更する必要はないと思います。

于 2012-09-10T16:40:41.473 に答える