本稿では、設定ファイルサイズが大きいhttpサーバとしてのNginxの起動速度をテストし、時間がかかる原因を分析します。
1.Nginxの初期化はlisten IP:PORTの影響を受け、ポートの収束によって初期化が非常に遅くなることがあります。
2.Server_nameの初期化は非常に高速で、初期化のパフォーマンスに影響はありません。
I. 試験内容
スクリプトは以下のルールで3種類の設定ファイルを作成します:
1.合計20,000のServer{}構成が作成されました。
2. サーバ名 基本固定長 PerformanceTestxxx
3.タイプ1は、リッスンIPは全く同じですが、ポートが異なり、設定ファイルの例です。
http{
server{
listen 192.:8080;
server_name PerformanceTest8080;
}
server{
listen 192.:8081;
server_name PerformanceTest8081;
.
}
}
3.タイプ 2 は、同一のポートと異なる IP、設定ファイルの例でリッスンします。
http{
server{
listen 192.:80;
server_name PerformanceTest1;
}
server{
listen 192.:80;
server_name PerformanceTest2;
.
}
}
4.クラス3はリッスンIP:PORTは全く同じですが、サーバー名は異なります、設定ファイルの例。
http{
server{
listen 192.:80;
server_name PerformanceTest001;
}
server{
listen 192.:80;
server_name PerformanceTest002;
.
}
}
試験データ
3種類のコンフィギュレーションの場合、3セットの変数を追加します。
1.サーバー名の設定なし
2. サーバー名が完全に設定されていること
3. server_nameは全体的に異なる設定になっています。
server_nameが初期化速度に与える影響を見てみましょう。
9つの組み合わせのパフォーマンスは以下の通り:
time ./nginx -c /root/nginx.conf.sameport.noloc
time ./nginx -c /root/nginx.conf.sameport.noloc -s reload
テストデータから、nginxの起動速度に影響を与える要因はserver{}のlistenポートであり、server_nameディレクティブは基本的に影響を与えないことがわかります。
原因の分析
3.1 http{}初期化処理の簡単な説明:
設定ファイルの解析は、http{}設定ブロックの解析処理であるngx_conf_parse関数を呼び出すことで再帰的に行われます:
1.http ディレクティブを解析し、ngx_http_ck 関数を実行し、http モジュールの設定コンテキストを作成し、 ngx_conf_parse に進んで http{} の内部コンテンツを解析します。
2.serverディレクティブをパースした後、ngx_http__er関数を実行してserver{}の設定コンテキストを作成し、ngx_conf_parseを続けてserver{}の内容をパースします。
3.listenコマンドを解析し、以下のようにcscfとcmcfの設定に追加します:
1. cmcf->servers 配列は、すべてのリスニングサーバーのデータを保持します。
構成はこんな感じ:
3.2 時間のかかる位置決め
コードに変数を追加して、関数が費やした合計時間を記録し、起動時に費やした時間を2段階で取得します。
1) ngx_conf_parse関数に対応する設定ファイルの解析
2) ngx_open_listening_sockets関数でソケットを初期化します。
3.3 ngx_conf_parse の時間消費分析
ngx_http_ck関数の主な時間消費は、以下の2つに分けられます:
明らかに、ngx__http__es 関数のパフォーマンスは、リニアトラバーサルルックアップが使用される、同じ rt の既存の ip のルックアップによって消費されます。
と文字列比較が必要な場合、ngx_memcmpは2w*2w回、合計4億回実行されました:
for (i = 0; i < port->addrs.nelts; i++) {
// 遍历查找, 如果配置文件中,相同port的IP过多,字符串比较带来较大性能问题, 2w个listen,这一块耗时需要8s左右
if (ngx_memcmp(p, addr[i].opt.u.sockaddr_data + off, len) != 0) {
continue;
}
/* the address is already in the address list */
// 找到对应的ip, 添加cscf到IP
if (ngx_http_add_server(cf, cscf, &addr[i]) != NGX_OK) {
return NGX_ERROR;
}
3.4 ngx_open_listening_sockets の時間消費分析
関数を使用してすべてのリスニング・ソケットを初期化します。
/* for each listening socket */
ls = cycle->listening.elts;
for (i = 0; i < cycle->listening.nelts; i++) {
if (bind(s, ls[i].sockaddr, ls[i].socklen) == -1) {
if (listen(s, ls[i].backlog) == -1) {
}
同じIPの場合、異なるIPで複数のソケットを作成するよりも、異なるポートで新しいソケットを作成する方が時間効率が高くなります。





