1. 背景 サーバーの開発プロセスでは、新しいコードや構成をロードするためにサービスを再起動することが避けられません。サーバーの再起動中にサービスが中断されないことが保証されれば、再起動によるビジネスへの影響をゼロにすることができます。最近、nginx のスムーズな再起動について調べて、とても興味深いと感じました。興味のある学生が読めるように記録しました。 2. プロセスを再起動する
3. nginxの実装 nginx のスムーズな再起動を検証するために、まず nginx の起動時に新しいサーバー インスタンスを再度起動してみました。結果は図のとおりです。 当然のことながら、古いサーバーと新しいサーバーは同じポート 80 を使用するため、サーバー インスタンスを再度開いても機能しません。ソケットの再利用ポート オプションが有効になっていない場合、ポートを再利用すると、bind システム コールは失敗します。デフォルトでは、nginx はバインドを 5 回再試行し、失敗するとすぐに終了します。 Nginx は IPV4 アドレス 0.0.0.0 と IPV6 アドレス [::] をリッスンする必要があるため、図には 10 個の emerg ログが出力されています。 次に、次の 2 つのコマンドで構成されるスムーズ再起動コマンドを試します。 kill -USR2 `cat /var/run/nginx.pid` キル -QUIT `cat /var/run/nginx.pid.oldbin` 最初のコマンドは、古いマスター プロセスに USR2 シグナルを送信します。プロセスの pid は /var/run/nginx.pid ファイルに保存されます。nginx.pid ファイル パスは nginx.conf によって設定されます。 2 番目のコマンドは、古いマスター プロセスに QUIT シグナルを送信します。プロセスの pid は /var/run/nginx.pid.oldbin ファイルに保存され、古いマスター プロセスは終了します。 それで疑問なのは、なぜ古いマスター プロセスの pid が 2 つの pid ファイルに存在するのかということです。実際、古いマスター プロセスに USR2 シグナルを送信した後、古いマスター プロセスは pid の名前を変更し、元の nginx.pid ファイルの名前が nginx.pid.oldbin に変更されました。このようにして、新しいマスターはファイル名 nginx.pid を使用できます。 まず最初のコマンドを実行すると、結果は次のようになります。 はい、古いマスタープロセスと新しいマスタープロセスおよびワーカープロセスが共存します。 2 番目のコマンドを実行してみましょう。結果は次のようになります。 ご覧のとおり、古いマスター プロセス 8527 とそのワーカー プロセスはすべて終了し、新しいマスター プロセス 12740 だけが残っています。 新しいインスタンスを手動で起動しても機能しないのに、シグナルで再起動すると機能するのはなぜなのか、不思議に思わざるを得ません。まず、nginx ログ ファイルを確認します。 前のエラー ログに加えて、ソケットが継承され、fd 値が 6 と 7 であることを示す通知がもう 1 つあります。 ログに従って、nginx ソース コードを調べ、nginx.c/ngx_exec_new_binary 関数を見つけました。 ngx_pid_t ngx_exec_new_binary(ngx_cycle_t *サイクル、char *const *argv) { ... ctx.path = argv[0]; ctx.name = "新しいバイナリプロセス"; ctx.argv = argv; 2; env = ngx_set_environment(サイクル、&n); ... var = ngx_alloc(sizeof(NGINX_VAR) + サイクル->listening.nelts * (NGX_INT32_LEN + 1) + 2、 サイクル->ログ); ... p = ngx_cpymem(var, NGINX_VAR "=", sizeof(NGINX_VAR)); ls = サイクル->listening.elts; (i = 0; i < cycle->listening.nelts; i++) { p = ngx_sprintf(p, "%ud;", ls[i].fd); } *p = '\0'; env[n++] = var; ... env[n] = NULL; ... ctx.envp = (char *const *) env; ccf は ngx_core_conf_t に格納されます。 ngx_rename_file(ccf->pid.data, ccf->oldpid.data) == NGX_FILE_ERROR の場合 { ... NGX_INVALID_PID を返します。 } pid = ngx_execute(サイクル、&ctx); (pid == NGX_INVALID_PID)の場合{ ngx_rename_file(ccf->oldpid.data, ccf->pid.data) の場合 == NGX_FILE_ERROR) { ... } } ... pid を返します。 } 機能フローは
静的 ngx_int_t ngx_add_inherited_sockets(ngx_cycle_t *cycle) { ... 継承 = (u_char *) getenv(NGINX_VAR); if (継承 == NULL) { NGX_OK を返します。 } if (ngx_array_init(&cycle->listening, cycle->pool, 10, サイズ(ngx_listening_t) != NGX_OK) { NGX_ERROR を返します。 } (p = 継承、v = p; *p; p++) { (*p == ':' || *p == ';') の場合 { s = ngx_atoi(v, p - v); ... v = p + 1; ls = ngx_array_push(&cycle->listening); ls == NULLの場合{ NGX_ERROR を返します。 } ngx_memzero(ls、sizeof(ngx_listening_t)); ls->fd = (ngx_socket_t) s; } } ... ngx_継承 = 1; ngx_set_inherited_sockets(cycle) を返します。 } 機能フローは次のとおりです。 環境変数NGINX_VARの値を解析し、配列に格納するfdを取得します。 これらのソケットの情報を保存するために、fd に対応するソケットが ngx_inherited に設定されます。 つまり、新しいサーバーは listen ポートをまったく再バインドしません。これらの fd の状態と値は、新しいマスター プロセスがフォークしたときに引き継がれます。新しいマスター プロセスは、継承されたファイル記述子を listen して処理できます。ここで重要な点は、listen ソケットのファイル記述子が ENV を介して渡されることです。 以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。 以下もご興味があるかもしれません:
|
<<: JSはGMTとUTCのタイムゾーンを完全に理解しています
導入前の記事で述べたように、NodeJS には 2 種類のスレッドがあります。1 つは、ユーザー リ...
目次序文1. 404 ページ1. 原因2. 解決策2.白い画面を更新する1. 原因2. 解決策3. ...
Linux で履歴レコードを表示し、タイムスタンプを追加するためのヒントbashに詳しい人なら、hi...
序文ページの HTML 構造にネストされたボックスが多数含まれている場合、ページに複数の垂直スクロー...
コード効果を異なるブラウザで表示することはよくあることなので、異なるショートカットキーを使用して対応...
フラットなウェブサイト構造の本質はシンプルさです。コンテンツの重要なポイントを強調し、ページの装飾効...
目次1. インストール2. インポート3. 検証ルールを定義します(エクスポート用に js ファイル...
目次序文1. データを抽出する2. エイリアス値3. 動的プロパティ4. オブジェクトの分解における...
目次プロトタイプチェーンプロトタイプチェーンに基づいてシンプルなJQueryライブラリを実装すること...
vue2 プロジェクト開発の経験があれば、$refs に精通しているでしょう。 vue3 の急激なア...
<br />では、CSS 構文を巧みに使用してテーブルを美しくする方法を見てみましょう。...
CentOS システムで MySQL データベース ディレクトリの場所を変更する方法1. まず、My...
目次JavaScript で配列を作成する配列の使用配列を分割文字列に変換する配列に要素を追加する配...
この記事では、 Webデザインに関連するこれら4 つの原則について説明します。これら4 つの原則を念...
1. ダウンロード1. MySQL公式サイトのダウンロードアドレス: https://downloa...