私は残りのサーバー( サーバーブロック )をincludeディレクティブでインクルードする1つのマスターnginx.confを持っています。
include myservers/*.conf;
私の問題は、myserversに新しい構成ファイルがある場合です。nginxをnginx -s reload
でリロードする必要があります
この問題は、サーバーのリロードに長い時間がかかり、1分ほどかかります。さらに多くの上流サーバーがあるので、これは大きくなります。
これを改善するためのテクニックはありますか?
私が今のところ見つけた唯一の解決策は、Nginx Nginx Plus APIの有料バージョンです https://docs.nginx.com/nginx/admin-guide/load-balancer/dynamic-configuration-api/ REST APIを使用して、新しいアップストリームサーバーを動的に追加できます。リロードは必要ありません。
また、スレーブサーバーに1つのマスターワースハッシュキーを使用した一種のシャーディングテクニック(コンセンサス状態を維持するためのRAFTアルゴリズムを使用したelasticsearchなど)があると考えていたため、更新する必要がある場合は、上流サーバーが少ないスレーブサーバーを1つだけ再ロードする必要があります。
nginx -s reload
が1分間かかっているファイルの数と構成の種類はありますか?
それを解決するためのソリューションを考え出すことができるようになる前に、そもそもなぜこれほど時間がかかるのかを理解する必要があると思います。
プロセスを遅くしているばかげた数の個別ファイルですか?
たとえば、cat myservers/*.conf | md5
を実行すると、1分で完了しますか?
その場合は、構成にRAMディスクを使用することを検討してください。または、個々の構成をデータベースに保持し、リロードのために単一のnginx.conf
を使用します。
リロードに非常に長い時間がかかるのは、構成ファイルの内容ですか?
これが問題になる可能性のある方法は複数ある可能性があります。
たとえば、構成の1つがドメイン名を使用していて(タイムアウトにより)解決に時間がかかり、リロード全体の速度が低下している可能性があります。 「正しい」入力が与えられた場合、単一のユーザーがリロードシーケンス全体を遅くできる可能性があるため、これはセットアップのセキュリティの脆弱性である可能性があります。
これは、構成に関する別の問題である可能性もあります。おそらく、多くの個別のログファイルを閉じたり開いたりする必要がある場合です。 lsof
や fstat
などのツールを使用してこれをさらに詳しく調べ、アプリケーションが使用する開いているファイルの数を確認できます。
他の人が指摘したように、現状のままでも、これはすでに大きな問題ではありません。nginx -s reload
は、構成の正常な再読み込みであるため、構成を再読み込みしても、nginxは完全に機能し続ける必要があるためです。
リロードをバッチにまとめ、5分から15分ごとに1回リロードを実行するのは、まったく理にかなっていると思います。新しいドメイン名を処理している場合は、おそらく、構成がDNSレベルで機能し始めるまで既に待機している必要があります。最大1分の遅延はまったく不合理ではなく、今日に至るまで、さまざまなクラウドプロバイダーのプロダクションサービスに非常に頻繁に実装されています。実際、DNSルートゾーンは多くの場合、バッチモードでも更新され、多くの場合、15分ごとに1回よりもはるかに少ない頻度で更新されます。たとえば、.ru
は500万件のレコードを持ち、冗長性のために複数の個別のプロバイダーによってミラーリングされるため、1日あたり4回だけ更新され、各更新には 最大30分 がかかるため、妥当なレベルの一貫性を確保し、個別の更新が相互に実行されないようにするには、間隔を空ける必要があります。
変更をすぐに反映させる必要がある場合は、おそらく別のアーキテクチャが必要です。おそらく、構成のテスト用に個別のステージング領域が用意されているもの、マルチレイヤアプローチ、またはnginxの商用バージョン、サードパーティのプラグインなどです。
問題の原因に応じて、解決策は、構成を行う方法を再設計することです。
問題の原因を知らなければ、質問は広すぎて特定のアドバイスを提供できません。
新しい仮想マシン(SSDバックアップストレージ付き)を起動し、nginxをインストールしました。次に、それぞれが単一のserver
ブロックを含む膨大な数のファイルを生成するスクリプトを作成しました。彼らはこのように見えました:
[root@localhost ~]# cat /etc/nginx/sites/server047393.conf
server {
listen 80;
listen [::]:80;
server_name server047393;
}
最初は5万個作成しましたが、nginxをリロードするのに9秒しかかかりませんでした。これにより、nginxをリロードするのに一貫して20秒かかりました。その時間の前半はディスクI/O待機で、後半はCPUでした。この数のサーバーブロックにより、nginxはほぼ1GiBのRAMを使用しています。
非常に遅いディスクにnginx設定がない限り、これは本当に問題のようには見えません。 nginxをリロードまたは再起動すると、全体が再読み込みされます。回転ディスクを使用すると、リロードに数分かかることがあります。 SSDを使用するか、RAMディスクを使用してnginx構成を保存します。
確かに、nginx自身の サーバー名の最適化のアドバイス は構成の解析時間についてほとんど言及していません。あまり気にする必要のないものです。それが多く話すのは、着信リクエストを処理するための正しいserver
ブロックを見つけるのにかかる時間です。デフォルトでは、nginxはこれを最適化して、CPUキャッシュラインミスを最小限に抑えようとします。
多数のサーバー名に対してこれを最適化するには、何もする必要はないかもしれませんが、おそらくserver_names_hash_max_size
ディレクティブを調整する必要があります。 nginx -t
を実行します。次のようなメッセージが表示された場合:
nginx: [warn] could not build optimal server_names_hash, you should increase either server_names_hash_max_size: 512 or server_names_hash_bucket_size: 64; ignoring server_names_hash_bucket_size
次に、server_names_hash_max_size
を調整する必要があります。まず、これを、作成しているserver_name
sの数よりも2の累乗に設定します。 30,000のサーバー名がある場合は、server_names_hash_max_size 32768
から始めます。
最適化ドキュメントはそれについて言及しています:
nginxの開始時間が許容できないほど長い場合は、
server_names_hash_bucket_size
を増やしてみてください。
テストでこれは実際には役に立たないことがわかりましたが、試したい場合は、毎回2の累乗で増やしてください。この値は2の累乗でなければなりません。そうでない場合、nginxは起動しません。この値はデフォルトでCPUキャッシュラインサイズに従って設定されるため、仮想マシンを使用していて、CPUプロパティがVMに正しく公開されていない場合、この数値を安全に2倍にすることができます(またはnginxが起動を拒否しました)そもそも、これは少し異なるエラーメッセージですcould not build the server_names_hash
)。それを使いすぎないでください。CPUキャッシュミスによって受信リクエストが遅くなります。
明白な(素朴な)アプローチは ramdisk を使用してから、定期的なバックアップをセットアップすることです。これは、ある種のフック(例:ユーザーがcPanelなどに変更を加えると、バックアップがトリガーされます。
これのバリエーションは、ディレクトリ全体をキャッシュとして強制的に処理することです。 vmtouch 。
ngx_postgres のようなものを使用して、構成の特定の部分をデータベースに移動する可能性もあります。 nginxがDBからの完全な設定のロードをサポートしていればはるかに良いでしょうが、私はそのようなことを知りません。
設定ファイルの量を削減する方向をとるこの非常に動的なアプローチはどうでしょうか。あなたの要件に応じて、それは前進する方法かもしれません: