Detaillierte Erläuterung der Verwendung des gemeinsam genutzten Speichers in Nginx

Detaillierte Erläuterung der Verwendung des gemeinsam genutzten Speichers in Nginx

Im Nginx-Prozessmodell erfordern Aufgaben wie Verkehrsstatistiken, Verkehrssteuerung und Datenfreigabe die Zusammenarbeit mehrerer Arbeitsprozesse, um Aufgaben zu erledigen. Der gemeinsam genutzte Speicher ist eine wichtige Lösung für die Prozesskommunikation. Dieser Artikel stellt die Funktionen im Zusammenhang mit dem gemeinsam genutzten Speicher im Nginx-Code vor, einschließlich der Verwendung und Vorsichtsmaßnahmen von ngx_shmem und ngx_slab, jedoch nicht den in ngx_slab implementierten Speicherverwaltungsalgorithmus.

Verwendung von ngx_shmem

Die Datei ngx_shmem.c/h ist nur ein sehr einfacher Wrapper für den Systemaufruf mmap()/munmap() oder shmget()/shmdt(). Implementierung der Basisbibliothek im ngx-Stil, die einen kontinuierlichen gemeinsam genutzten Speicherplatz beantragen und freigeben kann. Es wird im Allgemeinen für gemeinsam genutzte Daten mit fester Länge verwendet. Während der Verwendung ist die Datenlänge fest und wird nicht erweitert oder verkürzt.

typedef-Struktur {
  u_char *Adresse;
  size_t Größe;
  ...
} ngx_shm_t;
ngx_int_t ngx_shm_alloc(ngx_shm_t *shm);
void ngx_shm_free(ngx_shm_t *shm);

Der Nutzungsprozess des gemeinsam genutzten Speichers in ngxin wird im Allgemeinen vom Masterprozess erstellt, und der Workerprozess erhält den Speicherzeiger durch Vererbung.

Informationen zur Verwendung von ngx_shmem finden Sie in einigen Snippets in ngx_event_module_init(). Dieser Teil des Codes erstellt mehrere Variablen im gemeinsam genutzten Speicher, um die Anzahl der Anforderungen in jedem Status (akzeptiert/gelesen/geschrieben...) aufzuzeichnen, und führt Additions- und Subtraktionsstatistiken für diese Variablen bei mehreren wichtigen Ereigniseinträgen in ngx_event_module durch. Implementieren Sie Statistiken zum aktuellen Anforderungsstatus aller Arbeitsprozesse.

shm.size = Größe;
ngx_str_set(&shm.name, "nginx_shared_zone");
shm.log = Zyklus->Protokoll;

wenn (ngx_shm_alloc(&shm) != NGX_OK) {
  gib NGX_ERROR zurück;
}

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

Weitere Einzelheiten zu dieser Funktion finden Sie in der Makrodefinition NGX_STAT_STUB und im ngx_http_stub_status_module im Code.

Verwendung von ngx_slab

ngx_shmem ist eine minimalistische Kapselung, die die grundlegenden Funktionen des gemeinsam genutzten Speichers implementiert. Die meisten der gemeinsam genutzten Daten in unserem Programm sind jedoch keine Strukturen mit fester Größe, sondern ähneln eher ngx_array, ngx_list, ngx_queue, ngx_rbtree usw. Die Größe der Datenstruktur kann geändert werden.

Wir erwarten einen Speicherpool wie ngx_pool_t, der dynamisch Speicherplatz anfordern und freigeben kann. ngx_slab ist eine solche Struktur. Im Prinzip ähnelt es dem malloc() des Systems, indem es eine Reihe von Algorithmen verwendet, um Speichersegmente zu beantragen und freizugeben. Es ist nur so, dass das von ngx_slab betriebene Objekt der auf ngx_shmem basierende gemeinsam genutzte Speicher ist.

Schauen wir uns zunächst die Schnittstelle von ngx_slab an

typedef-Struktur {
  ngx_shmtx_t-Mutex;
  ...
  void *data; /* Speichert im Allgemeinen die aus dem Pool erhaltene Stammdatenadresse (die erste im Pool angeforderte Datenschnittstelle) */
  void *addr; /* Verwenden Sie ngx_shmem, um die Basisadresse des gemeinsam genutzten Speichers zu erhalten*/
} ngx_slab_pool_t;

ngx_slab_init(ngx_slab_pool_t *pool);
void *ngx_slab_alloc(ngx_slab_pool_t *pool, size_t Größe);
void *ngx_slab_alloc_locked(ngx_slab_pool_t *pool, size_t Größe);
void *ngx_slab_calloc(ngx_slab_pool_t *pool, size_t Größe);
void *ngx_slab_calloc_locked(ngx_slab_pool_t *pool, size_t Größe);
ngx_slab_free(ngx_slab_pool_t *pool, void *p);
void ngx_slab_free_locked(ngx_slab_pool_t *pool, void *p);

Es ist ersichtlich, dass die Schnittstelle nicht kompliziert ist. Der Unterschied zwischen alloc und calloc besteht darin, ob das von der Anwendung erhaltene Speichersegment gelöscht wird. Die mit _locked endende Schnittstelle zeigt an, dass der betriebene Pool die Sperre bereits erhalten hat. In der ngx_slab_pool_t-Struktur gibt es eine ngx_shmtx_t-Mutex-Sperre, die zum Synchronisieren gleichzeitiger Szenarien verwendet wird, in denen mehrere Prozesse gleichzeitig auf den Pool zugreifen. Beachten Sie, dass ngx_slab_alloc() zuerst die Sperre erwirbt, dann Speicherplatz anfordert und schließlich die Sperre freigibt. Allerdings wendet ngx_slab_alloc_locked() den Speicherplatz direkt an, vorausgesetzt, dass das Programm die Sperre bereits in einer anderen Logik erhalten hat.

Die Verwendung von ngx_shmem in der Nginx-Entwicklung erfordert im Allgemeinen den folgenden Initialisierungsprozess:

  • Das Modul ruft während des Konfigurationsanalyseprozesses die Schnittstelle ngx_shared_memory_add() auf, um ein gemeinsam genutztes Speichersegment zu registrieren. Bietet Rückruffunktionen für die gemeinsam genutzte Speichergröße und Speicherinitialisierung.
  • Das Framework verwendet ngx_shmem, um in ngx_init_cycle() Speicher zu beantragen, initialisiert ngx_slab und ruft dann die vom Modul registrierte Initialisierungsfunktion zurück.
  • Anwendung/Schnittstelle des Moduls mit ngx_slab

Dabei sind die Schnittstelle ngx_shared_memory_add() und die entsprechende Struktur ngx_shm_zone_t beteiligt.

Struktur ngx_shm_zone_s {
  ungültig *Daten;
  ngx_shm_t shm;
  ngx_shm_zone_init_pt init;
  void *tag;
  ungültig *synchronisieren;
  ngx_uint_t noreuse; /* unsigned noreuse:1; */
};
ngx_shm_zone_t *ngx_shared_memory_add(ngx_conf_t *cf, ngx_str_t *name,
  size_t Größe, void *tag);

Darunter ist das Attribut noreuse erwähnenswert, das steuert, ob der gemeinsam genutzte Speicher während des Neuladevorgangs von nginx erneut angewendet wird.

Da die Funktion ngx_init_cycle() lang ist, können Sie den relevanten Code anzeigen, indem Sie nach dem Kommentar /* create shared memory */ oder dem Objekt cycle->shared_memory suchen.

Für detailliertere Informationen zur Verwendung von ngx_slab wird empfohlen, ngx_http_limit_conn_module zu konsultieren. Dabei handelt es sich um ein Modul, das Verbindungslimits über gemeinsam genutzten Speicher implementiert. Das Modul weist eine geringe Komplexität auf und ist ein gutes Referenzbeispiel.

Verweise

Tiefgreifendes Verständnis von Nginx (2. Ausgabe) https://book.douban.com/subject/26745255/

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

Das Obige ist der vollständige Inhalt dieses Artikels. Ich hoffe, er wird für jedermanns Studium hilfreich sein. Ich hoffe auch, dass jeder 123WORDPRESS.COM unterstützen wird.

Das könnte Sie auch interessieren:
  • Detaillierte Erläuterung des Shared-Memory-Mechanismus von Nginx

<<:  Umfassende Referenz zur MySQL-Leistungsoptimierungsmethode, von der CPU über die Dateisystemauswahl bis hin zur mysql.cnf-Parameteroptimierung

>>:  Vier Lösungen für die Verwendung von setTimeout in JS for-Schleifen

Artikel empfehlen

Verstehen Sie die Prinzipien und Anwendungen von JSONP in einem Artikel

Inhaltsverzeichnis Was ist JSONP JSONP-Prinzip JS...

JavaScript-Objekte (Details)

Inhaltsverzeichnis JavaScript-Objekte 1. Definiti...

Apache Spark 2.0-Jobs brauchen lange, bis sie abgeschlossen sind

Phänomen Bei der Verwendung von Apache Spark 2.x ...

So starten und starten Sie nginx unter Linux neu

Nginx (Engine x) ist ein leistungsstarker HTTP- u...

Detaillierte Erklärung zur Konfiguration der OpenGauss-Datenbank im Docker

Für Windows-Benutzer Verwenden von openGauss in D...

Erfahren Sie in zehn Minuten, wie Sie Microservices mit Docker bereitstellen

Seit seiner Veröffentlichung im Jahr 2013 wird Do...

Lösungen für MySQL OOM (Speicherüberlauf)

OOM steht für „Out Of Memory“, was so viel bedeut...

Beispielcode einer in Vue3 gekapselten Lupenkomponente

Inhaltsverzeichnis Komponenteninfrastruktur Zweck...

Vier Methoden zur Datentypbeurteilung in JS

Inhaltsverzeichnis 1. Art von 2. Instanz von 3. K...

Seitenlayout für Bootstrap 3.0-Lernnotizen

Dieses Mal werden wir hauptsächlich etwas über da...

Vue3.0+vite2 implementiert dynamisches asynchrones Lazy Loading von Komponenten

Inhaltsverzeichnis Erstellen Sie ein Vite-Projekt...

Lösung für vergessenes Linux MySQL-Root-Passwort

Wenn Sie sich bei der Verwendung der MySQL-Datenb...

Webdesign muss Zweck, Ideen, Gedanken und Beständigkeit haben

<br />Einleitung: Diese Idee kam mir, als ic...