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 つのソリューション

推薦する

Windows 環境での MySQL 8.0 のインストール、設定、アンインストール

ソフトウェアバージョンウィンドウズ: ウィンドウズ10 MySQL: mysql-8.0.17-wi...

MySQL における Datetime と Timestamp の使用の概要

目次1. MySQL で現在の時刻を表現するにはどうすればよいでしょうか? 2. TIMESTAMP...

HTML外部参照CSSファイルが効果を発揮しない理由の分析と解決

フロントエンドの初心者として、私は数日間フロントエンドをいじってみました。 。今日、私は自分が固く信...

CSS 画像アニメーション効果のサンプルコード(フォトフレーム)

この記事では、CSS 画像アニメーション効果(フォトフレーム)のサンプルコードを紹介し、皆さんと共有...

Linux rpm および yum コマンドとその使用法の詳細な説明

RPM パッケージ管理インターネット ダウンロード パッケージのパッケージ化およびインストール ツー...

VUEはFlappy Birdゲームのサンプルコードを実装します

Flappy Bird は、誰もがアプリでプレイしたことがある非常にシンプルな小さなゲームです。ここ...

VMware Workstation に Windows Server 2019 をインストールする (グラフィック チュートリアル)

キーの入力を求められた場合は、[キーがありません]を選択します。デスクトップエクスペリエンスを選択す...

フロントエンドのパフォーマンス最適化を学習するための準備として、HTML ページのレンダリング プロセスを理解する (続き)

昨夜、ブラウザのレンダリングプロセスに関するエッセイを書きましたが、小さなコードで説明しただけでした...

SSL を実装するために nginx を設定する方法の例

環境説明サーバーシステム: Ubuntu 18.04 64ビットnginx: 1.14この記事では主...

MySQL コマンドラインでよく使われる 18 個のコマンド

日常的なウェブサイトの保守と管理では、多くの SQL ステートメントが使用されます。熟練して使用する...

Vueはログインタイプの切り替えを実装します

この記事では、ログインタイプの切り替えを実装するためのVueの具体的なコードを例として紹介します。具...

Navicat 8でMySQL用のデータベースを作成する方法

ウェブサイトを開発する場合、データを保存するためにデータベースを使用する必要があることがよくあります...

IDEA は Docker プラグインを使用します (初心者向けチュートリアル)

目次例示する1. Dockerリモートアクセスを有効にする2. Dockerに接続する3. イメージ...

Nginx ロードバランシングの設定方法

目次Nginx 負荷分散構成Nginx 負荷分散戦略ポーリング(デフォルト)重さip_ハッシュ公正(...

3分でUbuntu 16.04を初期化し、Java、Maven、Docker環境をデプロイする

Fast-Linux プロジェクト アドレス: https://gitee.com/uitc/Fas...