nginxでの共有メモリの使用に関する詳細な説明

nginxでの共有メモリの使用に関する詳細な説明

nginx プロセス モデルでは、トラフィック統計、トラフィック制御、データ共有などのタスクを完了するには、複数の作業プロセスが連携して動作する必要があります。共有メモリは、重要なプロセス通信ソリューションです。この記事では、ngx_shmem と ngx_slab の使い方や注意点など、nginx コード内の共有メモリに関連する機能を紹介しますが、ngx_slab に実装されているメモリ管理アルゴリズムについては取り上げません。

ngx_shmemの使用

ngx_shmem.c/h ファイルは、mmap()/munmap() システム コールまたは shmget()/shmdt() の非常に単純なラッパーです。連続した共有メモリ空間の申請と解放が可能な ngx スタイルの基本ライブラリを実装しました。一般的には固定長の共有データに使用されます。使用中はデータ長が固定され、拡張または縮小されません。

typedef構造体{
  u_char *アドレス;
  size_t サイズ;
  ...
} ngx_shm_t;
shm は、 ngx_int_t 型の配列です。
ngx_shm_free() を呼び出します。

ngxin における共有メモリの使用プロセスは、通常、マスタープロセスによって作成され、ワー​​カープロセスは継承によってメモリポインタを取得します。

ngx_shmem の使用については、ngx_event_module_init() のいくつかのスニペットを参照できます。コードのこの部分では、共有メモリにいくつかの変数を作成し、各状態 (承認済み/読み取り/書き込み中など) のリクエスト数を記録し、ngx_event_module のいくつかの主要なイベント エントリでこれらの変数の統計の加算と減算を実行します。すべてのワーカー プロセスの現在の要求ステータスに関する統計を実装します。

shm.size = サイズ;
ngx_str_set(&shm.name, "nginx_shared_zone");
shm.log = サイクル->ログ;

ngx_shm_alloc(&shm) が NGX_OK の場合 {
  NGX_ERROR を返します。
}

共有 = shm.addr;
...
ngx_stat_accepted = (ngx_atomic_t *) (shared + 3 * cl);
ngx_stat_handled = (ngx_atomic_t *) (共有 + 4 * cl);
ngx_stat_requests = (ngx_atomic_t *) (共有 + 5 * cl);
ngx_stat_active = (ngx_atomic_t *) (共有 + 6 * cl);
ngx_stat_reading = (ngx_atomic_t *) (共有 + 7 * cl);
ngx_stat_writing = (ngx_atomic_t *) (共有 + 8 * cl);
ngx_stat_waiting = (ngx_atomic_t *) (共有 + 9 * cl);

この機能の詳細については、NGX_STAT_STUB マクロ定義とコード内の ngx_http_stub_status_module を参照してください。

ngx_slabの使用

ngx_shmem は、共有メモリの基本機能を実装する最小限のカプセル化です。ただし、プログラム内の共有データのほとんどは固定サイズの構造ではなく、ngx_array、ngx_list、ngx_queue、ngx_rbtree などのデータ構造のサイズは変更できます。

動的にスペースを要求および解放できる ngx_pool_t のようなメモリ プールが必要になると予想されます。 ngx_slab はそのような構造です。原理的には、一連のアルゴリズムを使用してメモリ セグメントを適用および解放するという点で、システムの malloc() に似ています。ただ、ngx_slab が操作するオブジェクトは ngx_shmem に基づく共有メモリです。

まずはngx_slabのインターフェースを見てみましょう

typedef構造体{
  ngx_shmtx_t ミューテックス;
  ...
  void *data; /* 通常はプールから取得したルートデータアドレス(プールで要求された最初のデータインターフェイス)を格納します */
  void *addr; /* ngx_shmem を使用して共有メモリのベースアドレスを取得します*/
} ngx_slab_pool_t;

ngx_slab_init() を呼び出します。
void *ngx_slab_alloc(ngx_slab_pool_t *プール、size_t サイズ);
void *ngx_slab_alloc_locked(ngx_slab_pool_t *プール、size_t サイズ);
void *ngx_slab_calloc(ngx_slab_pool_t *プール、size_t サイズ);
void *ngx_slab_calloc_locked(ngx_slab_pool_t *プール、size_t サイズ);
ngx_slab_free は、プールからデータを解放します。
ngx_slab_free_locked を void に設定します。

インターフェースは複雑ではないことがわかります。alloc と calloc の違いは、アプリケーションが取得したメモリ セグメントがクリアされるかどうかにあります。_locked で終わるインターフェースは、操作対象のプールがすでにロックを取得していることを示します。 ngx_slab_pool_t 構造には、複数のプロセスが同時にプールにアクセスする同時シナリオを同期するために使用される ngx_shmtx_t ミューテックス ロックがあります。 ngx_slab_alloc() は最初にロックを取得し、次にスペースを適用し、最後にロックを解放することに注意してください。ただし、ngx_slab_alloc_locked() は、プログラムがすでに他のロジックでロックを取得していると想定して、スペースに直接適用されます。

nginx 開発で ngx_shmem を使用するには、通常、次の初期化プロセスが必要です。

  • モジュールは、構成解析プロセス中に ngx_shared_memory_add() インターフェースを呼び出して、共有メモリ セグメントを登録します。共有メモリのサイズとメモリの初期化のためのコールバック関数を提供します。
  • フレームワークは、ngx_shmem を使用して ngx_init_cycle() でメモリを適用し、ngx_slab を初期化してから、モジュールによって登録された初期化関数をコールバックします。
  • ngx_slab を使用したモジュールのアプリケーション/インターフェース

このプロセスには、ngx_shared_memory_add() インターフェースと対応する ngx_shm_zone_t 構造が関与します。

構造体 ngx_shm_zone_s {
  void *データ;
  ngx_shm_t shm;
  ngx_shm_zone_init_pt を初期化します。
  void *タグ;
  void *同期;
  ngx_uint_t noreuse; /* 符号なし noreuse:1; */
};
ngx_shm_zone_t *ngx_shared_memory_add(ngx_conf_t *cf, ngx_str_t *name,
  size_t サイズ、void *タグ);

その中でも、nginx のリロード プロセス中に共有メモリが再適用されるかどうかを制御する noreuse 属性について言及する価値があります。

ngx_init_cycle() 関数は長いため、コメント /* create shared memory */ または cycle->shared_memory オブジェクトを探すことで、関連するコードを表示できます。

ngx_slab の使用に関する詳細については、共有メモリを介して接続制限を実装するモジュールである ngx_http_limit_conn_module を参照することをお勧めします。このモジュールは複雑さが低く、優れた参考例です。

参考文献

Nginx 徹底理解(第 2 版) https://book.douban.com/subject/26745255/

ngx_http_limit_conn_module http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html

以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • nginx共有メモリの仕組みの詳細な説明

<<:  MySQL パフォーマンスの包括的な最適化方法リファレンス、CPU、ファイルシステムの選択から mysql.cnf パラメータの最適化まで

>>:  JS for ループで setTimeout を使用する 4 つのソリューション

推薦する

Mysql テーブルで利用可能な最小 ID 値を照会する方法

今日、研究室のプロジェクトを見ていたとき、私にとって「難しい」問題に遭遇しました。実は、それは私があ...

トップ 10 Js 画像処理ライブラリ

目次導入1. 異食症2. レナ3. コンプレッサー4. ファブリック5. ぼかす6. 画像を結合する...

MySQL/MariaDB で完全な Unicode をサポートする方法

目次utf8mb4 の紹介UTF8 バイト数超過エラーutf8mb4 サポートデフォルトの文字エンコ...

yum インストールエラーの問題を解決する 保護されたマルチライブラリバージョン

現在、クラウドサーバーに nginx をインストールする際、最初に zlib などの依存ライブラリを...

CSS でフローティングにより親要素の高さが崩れる問題を解決するいくつかの方法

1. ドキュメントフローとフローティング1. ドキュメントフローとは何ですか? HTML では、ドキ...

JavaScript を使用して QR コードを解析する 3 つの方法

目次1. JavaScriptを使用してQRコードを解析する1. QR コードとは何ですか? 2.q...

DockerコンテナのIPアドレスを取得する方法の詳細な説明

1.コンテナに入った後 /etc/hosts を cat するコンテナ自体の IP アドレスと (-...

Linuxで同一ファイルを見つける方法

コンピュータを使用すると、システム内に大量のゴミが生成されます。最も一般的なケースは、同じファイルが...

Webpack で環境変数を使用するためのさまざまな正しい姿勢

目次前に書いてビジネスコードは環境変数を使用するwebpack.DefinePlugin プラグイン...

Ubuntu 18.04 は mysql 5.7.23 をインストールします

以前、Ubuntu 16.04 に MySQL をスムーズにインストールしました。今回、Ubuntu...

MySQL データベース内の同じテーブルを同時にクエリして更新する方法

通常のプロジェクトでは、1 回の入札で同時にデータを更新および照会する必要があるという問題によく遭遇...

Baota Linux パネル コマンド リスト

目次Pagodaをインストールする管理塔Nginx サービス管理Apache サービス管理MySQL...

Linux 仮想メモリ設定のチュートリアルと実践

仮想メモリとは何ですか?まずはWikipediaからの紹介文をそのまま引用します。仮想メモリは、コン...

ドロップダウンボックス選択コンポーネントを実装するためのネイティブ js

この記事の例では、ドロップダウンボックス選択コンポーネントを実装するためのjsの具体的なコードを参考...

適応型ウェブページを設計および作成する方法

3G の普及により、携帯電話を使ってインターネットにアクセスする人が増えています。モバイル デバイス...