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

推薦する

Dockerコンテナにnginxを簡単にデプロイするプロセスの分析

1. コンテナにnginxサービスをデプロイするcentos:7 イメージはコンテナを実行し、このコ...

Javascript での JSBridge に関する予備的研究

目次JSBridgeの起源JSBridgeの双方向通信原理JSはネイティブを呼び出すネイティブコール...

VMware Workstation16 と Navicat リモート接続での Centos7 での MySQL8.0 インストール プロセス

目次1. CentOS7+MySQL8.0、yumソースインストール2. MySQLにログインしてパ...

一般的な JavaScript 文字列メソッド 28 個と使用方法のヒントのまとめ

目次序文1. 文字列の長さを取得する2. 文字列の指定された位置の値を取得する(1) charAt(...

MySQL の制限パフォーマンス分析と最適化

1. 結論構文: 制限オフセット、行結論: 同じ行条件では、オフセット値が大きいほど、limitステ...

MySQL データ型の選択原則

目次小さいけれど美しいシンプルにNULL値を避けるデータタイプを選択する手順データ型の紹介1. 文字...

ビューポートの基本原理と詳細な使用方法

1. ビューポートの概要モバイル ブラウザは通常、画面よりも幅の広い仮想ウィンドウにページをレンダリ...

PHP スケジュールバックアップ MySQL および mysqldump 構文パラメータの詳細

まず、MySQL バックアップ コマンド mysqldump の一般的な操作例をいくつか紹介します。...

MySQL で中国語を入力するときに発生するエラー 1366 の解決方法

MySQL で中国語を入力すると、次のエラーが発生します。エラー 1366: 1366: 行 1 の...

よく使われる HTML タグとその特徴の完全なリスト

まず、HTML タグのいくつかの特性を知っておく必要があります。 1. 「<keyword&g...

IE で ClearType をオンにした後の透明フォントの問題の解決方法

IE で ClearType をオンにした後に発生する透明フォントの問題を解決するには、透明要素に背...

サーバー同時実行数の推定式と計算方法

最近、サーバーのストレステストを再度行う必要が出てきました。ここでは、最近学んだ見積もりスキームと見...

SSL で Nginx リバース プロキシを構成する簡単な手順

序文リバース プロキシは、Web 経由で行われたリクエスト (http と https の両方) を...

MySQL アクティブ-アクティブ同期レプリケーションの 4 つのソリューションの詳細な説明

目次MySQLネイティブレプリケーションに基づくマスター-マスター同期ソリューションGaleraレプ...

高度な CSS の 3 つの方法を使用して複数行の省略を実装するサンプル コード

序文これは古くからの要望ですが、オンラインで解決策を探している人はまだ多く、特に検索結果の上位にラン...