検索
ホームページ運用・保守Nginxnginxでスムーズな再起動を実現する方法

一、背景

在服务器开发过程中,难免需要重启服务加载新的代码或配置,如果能够保证server重启的过程中服务不间断,那重启对于业务的影响可以降为0。

二、重启流程

  •  重启意味着新旧接替,在交接任务的过程中势必会存在新旧server并存的情形,因此,重启的流程大致为:

    • 启动新的server

    • 新旧server并存,两者共同处理请求,提供服务

    • 旧的server处理完所有的请求之后优雅退出

  • 这里,最主要的问题在于如何保证新旧server可以并存,如果重启前后的server端口一致,如何保证两者可以监听同一端口。

 三、nginx实现

为了验证nginx平滑重启,笔者首先尝试nginx启动的情形下再次开启一个新的server实例,结果如图:

nginxでスムーズな再起動を実現する方法

很明显,重新开启server实例是行不通的,原因在于新旧server使用了同一个端口80,在未开始socket reuseport选项复用端口时,bind系统调用会出错。nginx默认bind重试5次,失败后直接退出。而nginx需要监听ipv4地址0.0.0.0和ipv6地址[::],故图中打印出10条emerg日志。

接下来就开始尝试平滑重启命令了,一共两条命令:

kill -usr2 `cat /var/run/nginx.pid`
kill -quit `cat /var/run/nginx.pid.oldbin`

第一条命令是发送信号usr2给旧的master进程,进程的pid存放在/var/run/nginx.pid文件中,其中nginx.pid文件路径由nginx.conf配置。

第二条命令是发送信号quit给旧的master进程,进程的pid存放在/var/run/nginx.pid.oldbin文件中,随后旧的master进程退出。

那么问题来了,为什么旧的master进程的pid存在于两个pid文件之中?事实上,在发送信号usr2给旧的master进程之后,旧的master进程将pid重命名,原先的nginx.pid文件rename成nginx.pid.oldbin。这样新的master进行就可以使用nginx.pid这个文件名了。

先执行第一条命令,结果如图:

nginxでスムーズな再起動を実現する方法

不错,新旧master和worker进程并存了。 再来第二条命令,结果如图:

nginxでスムーズな再起動を実現する方法

如你所见,旧的master进程8527和其worker进程全部退出,只剩下新的master进程12740。

不由得产生困惑,为什么手动开启一个新的实例行不通,使用信号重启就可以达到。先看下nginx log文件:

nginxでスムーズな再起動を実現する方法

除了之前的错误日志,还多了一条notice,意思就是继承了sockets,fd值为6,7。 随着日志翻看nginx源码,定位到nginx.c/ngx_exec_new_binary函数之中,

ngx_pid_t
ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv)
{
  ...
  ctx.path = argv[0];
  ctx.name = "new binary process";
  ctx.argv = argv;
  n = 2;
  env = ngx_set_environment(cycle, &n);
...
  var = ngx_alloc(sizeof(nginx_var)
          + cycle->listening.nelts * (ngx_int32_len + 1) + 2,
          cycle->log);
...
  p = ngx_cpymem(var, nginx_var "=", sizeof(nginx_var));
  ls = cycle->listening.elts;
  for (i = 0; i < cycle->listening.nelts; i++) {
    p = ngx_sprintf(p, "%ud;", ls[i].fd);
  }
  *p = &#39;\0&#39;;
  env[n++] = var;
...
  env[n] = null;
...
  ctx.envp = (char *const *) env;
  ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
  if (ngx_rename_file(ccf->pid.data, ccf->oldpid.data) == ngx_file_error) {
    ...
    return ngx_invalid_pid;
  }
  pid = ngx_execute(cycle, &ctx);
  if (pid == ngx_invalid_pid) {
    if (ngx_rename_file(ccf->oldpid.data, ccf->pid.data)
      == ngx_file_error)
    {
      ...
    }
  }
...
  return pid;
}

函数的流程为

  1.  将旧的master进程监听的所有fd,拷贝至新master进程的env环境变量nginx_var。

  2. rename重命名pid文件

  3. ngx_execute函数fork子进程,execve执行命令行启动新的server。

  4. 在server启动流程之中,涉及到环境变量nginx_var的解析,ngx_connection.c/ngx_add_inherited_sockets具体代码为:

static ngx_int_t
ngx_add_inherited_sockets(ngx_cycle_t *cycle)
{
...
  inherited = (u_char *) getenv(nginx_var);
  if (inherited == null) {
    return ngx_ok;
  }
  if (ngx_array_init(&cycle->listening, cycle->pool, 10,
            sizeof(ngx_listening_t))
    != ngx_ok)
  {
    return ngx_error;
  }
  for (p = inherited, v = p; *p; p++) {
    if (*p == &#39;:&#39; || *p == &#39;;&#39;) {
      s = ngx_atoi(v, p - v);
      ...
      v = p + 1;
      ls = ngx_array_push(&cycle->listening);
      if (ls == null) {
        return ngx_error;
      }
      ngx_memzero(ls, sizeof(ngx_listening_t));
      ls->fd = (ngx_socket_t) s;
    }
  }
  ...
  ngx_inherited = 1;
  return ngx_set_inherited_sockets(cycle);
}

函数流程为:

解析环境变量nginx_var的值,获取fd存入数组

fd对应的socket设为ngx_inherited,保存这些socket的信息。

也就是说,新的server压根就没重新bind端口listen,这些fd状态和值都是新的master进程fork时带过来的,新的master进程监听处理继承来的文件描述符即可,这里比较关键的一点在于listen socket文件描述符通过env传递。

以上がnginxでスムーズな再起動を実現する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事は亿速云で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
Nginxユニット:さまざまなプログラミング言語をサポートしますNginxユニット:さまざまなプログラミング言語をサポートしますApr 16, 2025 am 12:15 AM

Nginxunitは複数のプログラミング言語をサポートし、モジュラー設計を通じて実装されています。 1。言語モジュールの読み込み:構成ファイルに従って対応するモジュールをロードします。 2。アプリケーションの起動:呼び出し言語が実行されたときにアプリケーションコードを実行します。 3。リクエスト処理:リクエストをアプリケーションインスタンスに転送します。 4。応答返品:処理された応答をクライアントに返します。

nginxとapacheを選択する:あなたのニーズに合った適切nginxとapacheを選択する:あなたのニーズに合った適切Apr 15, 2025 am 12:04 AM

NginxとApacheには独自の利点と短所があり、さまざまなシナリオに適しています。 1.Nginxは、高い並行性と低リソース消費シナリオに適しています。 2。Apacheは、複雑な構成とリッチモジュールが必要なシナリオに適しています。コア機能、パフォーマンスの違い、ベストプラクティスを比較することで、ニーズに最適なサーバーソフトウェアを選択するのに役立ちます。

nginxを開始する方法nginxを開始する方法Apr 14, 2025 pm 01:06 PM

質問:nginxを開始する方法は?回答:nginxスタートアップnginx検証nginxはnginxを開始しました他のスタートアップオプションを自動的に開始

Nginxが開始されるかどうかを確認する方法Nginxが開始されるかどうかを確認する方法Apr 14, 2025 pm 01:03 PM

nginxが開始されるかどうかを確認する方法:1。コマンドラインを使用します:SystemCTLステータスnginx(Linux/unix)、netstat -ano | FindStr 80(Windows); 2。ポート80が開いているかどうかを確認します。 3.システムログのnginx起動メッセージを確認します。 4. Nagios、Zabbix、Icingaなどのサードパーティツールを使用します。

nginxを閉じる方法nginxを閉じる方法Apr 14, 2025 pm 01:00 PM

NGINXサービスをシャットダウンするには、次の手順に従ってください。インストールタイプを決定します:Red Hat/Centos(SystemCtl Status Nginx)またはDebian/Ubuntu(Service Nginx Status)サービスを停止します:Red Hat/Centos(SystemCtl Stop Nginx)またはDebian/Ubuntu(Service Nginx Stop)無効自動起動(オプション):Debuntos/Centos/Centos/Centos/Centos/Centos (syst

Windowsでnginxを構成する方法Windowsでnginxを構成する方法Apr 14, 2025 pm 12:57 PM

Windowsでnginxを構成する方法は? nginxをインストールし、仮想ホスト構成を作成します。メイン構成ファイルを変更し、仮想ホスト構成を含めます。 nginxを起動またはリロードします。構成をテストし、Webサイトを表示します。 SSLを選択的に有効にし、SSL証明書を構成します。ファイアウォールを選択的に設定して、ポート80および443のトラフィックを許可します。

nginx403エラーを解く方法nginx403エラーを解く方法Apr 14, 2025 pm 12:54 PM

サーバーには、要求されたリソースにアクセスする許可がなく、NGINX 403エラーが発生します。ソリューションには以下が含まれます。ファイル許可を確認します。 .htaccess構成を確認してください。 nginx構成を確認してください。 SELINUXアクセス許可を構成します。ファイアウォールルールを確認してください。ブラウザの問題、サーバーの障害、その他の可能なエラーなど、他の原因をトラブルシューティングします。

Linuxでnginxを開始する方法Linuxでnginxを開始する方法Apr 14, 2025 pm 12:51 PM

Linuxでnginxを開始する手順:nginxがインストールされているかどうかを確認します。 systemctlを使用して、nginxを開始してnginxサービスを開始します。 SystemCTLを使用して、NGINXがシステムスタートアップでNGINXの自動起動を有効にすることができます。 SystemCTLステータスNGINXを使用して、スタートアップが成功していることを確認します。 Webブラウザのhttp:// localhostにアクセスして、デフォルトのウェルカムページを表示します。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

Dreamweaver Mac版

Dreamweaver Mac版

ビジュアル Web 開発ツール

PhpStorm Mac バージョン

PhpStorm Mac バージョン

最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

SublimeText3 英語版

SublimeText3 英語版

推奨: Win バージョン、コードプロンプトをサポート!

DVWA

DVWA

Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

mPDF

mPDF

mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。