Ab diesem Abschnitt erklären wir das Implementierungsprinzip des http-Moduls. Ein sehr wichtiger Punkt beim http-Modul ist, wie es Daten im http-Block, Serverblock und Standortblock speichert. Einige Konfigurationselemente von nginx können in mehreren Konfigurationsblöcken verwendet werden. Wenn zwei oder mehr Konfigurationsblöcke im http-Block, Serverblock und Standortblock mit dem Konfigurationselement konfiguriert werden, stellt sich die Frage, wie nginx diese Konfigurationselemente verarbeitet. In diesem Artikel wird hauptsächlich erläutert, wie die Daten jedes Moduls im HTTP-Block gespeichert werden. Dies ist ein wichtiger Grundstein für das Verständnis der Funktionsweise des HTTP-Moduls von Nginx. 1. Speichermethode für Kernmodule Während der Ausführung von nginx gibt es eine globale Konfigurationsstruktur ngx_cycle_t , die ein Attribut conf_ctx hat. Dieses Attribut ist ein Array, das die Konfiguration aller nginx-Module speichert. Die Länge dieses Arrays entspricht der Anzahl der nginx-Module. Es ist jedoch zu beachten, dass die erste Dimension des conf_ctx -Arrays nur die Konfiguration des Kernmoduls speichert und die Array-Elemente an den entsprechenden Positionen anderer Module tatsächlich NULL sind. In conf_ctx stimmt der Speicherort der Konfigurationsstruktur jedes Kernmoduls mit der relativen Position des Moduls in allen Modulen (einschließlich Nicht-Kernmodulen) überein. Die folgende Abbildung ist ein Strukturdiagramm der Speicherkernmodule von nginx: 
events und http werden nur zur Vereinfachung der Demonstration hinzugefügt. Im Wesentlichen ist der Typ der Elemente dieses Arrays ein void* -Zeiger. Der Typ der spezifischen Struktur, auf die der Zeiger zeigt, basiert auf der Definition jedes Kernmoduls selbst. Unter dem http-Modul verweist es auf eine Struktur vom Typ ngx_http_conf_ctx_t , die zum Speichern der Daten jedes Konfigurationselements im http-Konfigurationsblock verwendet wird. Die Definition dieser Struktur lautet wie folgt:
typedef-Struktur {
//Konfiguration auf MAIN-Ebene speichern void **main_conf;
//Konfiguration auf SRV-Ebene speichern void **srv_conf;
//Konfiguration auf LOC-Ebene speichern void **loc_conf;
} ngx_http_conf_ctx_t; Wir wissen, dass sich in der Konfigurationsdatei nginx.conf unter dem http-Block ein Serverblock befindet und dass sich unter dem Serverblock ein Standortblock befinden kann. Darüber hinaus kann sich unter dem Standortblock ein untergeordneter Standortblock befinden usw. Die Rolle der Struktur ngx_http_conf_ctx_t besteht hier darin, die Strukturdaten zu speichern, die all diesen Konfigurationen entsprechen. Zunächst müssen wir klarstellen, dass in der Konfigurationsdatei nginx.conf Konfigurationselemente durch Module definiert werden. Ein Modul kann mehrere Konfigurationselemente definieren, und die Analyse dieser Konfigurationselemente erfolgt durch die von diesem Modul definierten Methoden. Im Allgemeinen definiert ein Modul jedoch nur eine Struktur, und die verschiedenen Attribute in dieser Struktur entsprechen den Daten jedes vom Modul definierten Konfigurationselements. Das heißt, durch die von jedem Modul definierten Methoden konvertiert es die Konfiguration, die dem von ihm definierten Konfigurationselement entspricht, in die vom Modul definierte Struktur. Der hier genannte Aufbau entspricht der Konfiguration in main_conf , srv_conf und loc_conf weiter oben. Aus der obigen Definition können wir erkennen, dass die Typen dieser drei Attribute Arrays von Zeigertypen sind und die Länge des Arrays der Anzahl der Module oder genauer gesagt der Anzahl der HTTP-Module entspricht. Bevor die Konfiguration jedes HTTP-Moduls analysiert wird, markiert Nginx die relative Position jedes HTTP-Moduls im aktuellen Modultyp (HTTP-Modul). Die relative Position jedes HTTP-Moduls entspricht dem Array-Index der oben genannten drei Attribute. Wie bereits erwähnt, verfügt jedes HTTP-Modul nur über eine Konfigurationsstruktur zum Speichern aller vom Modul definierten Konfigurationsdaten, und diese Konfigurationsstrukturen werden in den drei oben genannten Arrays gespeichert. Auf diese Weise können wir verstehen, dass tatsächlich jedes der drei Attribute der obigen Struktur, nämlich das Array, einer Konfigurationsstruktur des http-Moduls entspricht. Da jedes Modul hier eine Struktur hat, die an der entsprechenden Indexposition des Arrays gespeichert ist, warum werden hier drei Arrays benötigt? Beispielsweise ist für ngx_http_core_module die relative Position im http-Modul die erste, das heißt, main_conf[0] , srv_conf[0] und loc_conf[0] speichern alle die Konfigurationsstruktur von ngx_http_core_module . Warum werden drei Strukturen benötigt? Was wir hier erklären müssen, ist, dass für jedes http-Modul die Konfigurationselemente entsprechend dem Verwendungsumfang in drei Kategorien unterteilt werden: nur für http-Block, kann für http-Block und Serverblock verwendet werden und kann für http-Block, Serverblock und Standortblock verwendet werden. Jeder Konfigurationselementtyp verwendet eine andere Struktur. Beispielsweise definiert ngx_http_core_module ngx_http_core_main_conf_t um Konfigurationselemente zu speichern, die nur für den HTTP-Block verwendet werden, ngx_http_core_srv_conf_t , um Konfigurationselemente zu speichern, die für den HTTP-Block und den Serverblock verwendet werden, und ngx_http_core_loc_conf_t um Konfigurationselemente zu speichern, die für den HTTP-Block, den Serverblock und den Standortblock verwendet werden. Entsprechend dem obigen Array ist der Strukturtyp von main_conf[0] ngx_http_core_main_conf_t , der Strukturtyp von srv_conf[0] ist ngx_http_core_srv_conf_t und der Strukturtyp von loc_conf[0] ist ngx_http_core_loc_conf_t . An dieser Stelle müssen wir ein Problem klären. Beispielsweise wird ein bestimmtes Konfigurationselement im http-Block konfiguriert, sein Typ kann jedoch im http-Block, Serverblock und Standortblock verwendet werden, dann wird er in loc_conf[0] gespeichert. Mit anderen Worten speichert die gesamte obige Struktur aus heutiger Sicht die Daten jedes Konfigurationselements, das im http-Block analysiert wird. Wie also markiert Nginx, um welchen dieser drei Typen es sich bei einem Konfigurationselement handelt? Dies wird hauptsächlich durch die ngx_command_t Struktur definiert. Im Folgenden sind drei typische Konfigurationen aufgeführt:
{
ngx_string("maximale Hashgröße der Variablen"),
NGX_HTTP_MAIN_CONF | NGX_CONF_TAKE1,
ngx_conf_set_num_slot,
NGX_HTTP_MAIN_CONF_OFFSET,
Offset von (ngx_http_core_main_conf_t, maximale Hash-Größe der Variablen),
NULL
},
{
ngx_string("hören"),
NGX_HTTP_SRV_CONF | NGX_CONF_1MEHR,
ngx_http_core_listen,
NGX_HTTP_SRV_CONF_OFFSET,
0,
NULL
},
{
ngx_string("Wurzel"),
NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_HTTP_LIF_CONF
| NGX_CONF_TAKE1,
ngx_http_core_root,
NGX_HTTP_LOC_CONF_OFFSET,
0,
NULL
}, Hier nehmen wir variables_hash_max_size , listen und root als Beispiele. Diese drei Anweisungen sind Konfigurationselemente, die vom Modul ngx_http_core_module definiert werden, aber ihre Speicherorte sind völlig unterschiedlich. Wir müssen auf die Definition des vierten Attributs jeder Direktive achten: NGX_HTTP_MAIN_CONF_OFFSET , NGX_HTTP_SRV_CONF_OFFSET und NGX_HTTP_LOC_CONF_OFFSET . Die Definition dieser drei Typen hat zwei Bedeutungen. Eine besteht darin, anzugeben, ob dieses Konfigurationselement nur für HTTP-Blöcke verwendet wird oder für HTTP-Blöcke und Serverblöcke verwendet werden kann oder für HTTP-Blöcke, Serverblöcke und Standortblöcke verwendet werden kann. Die andere Bedeutung besteht darin, den Offset dieses Konfigurationselements im oben erwähnten ngx_http_conf_ctx_t zu definieren. Der sogenannte Offset bedeutet, dass, wenn die Zeigeradresse des Strukturobjekts ngx_http_conf_ctx_t bekannt ist, das im aktuellen Konfigurationselement gespeicherte Array hier über den Offset berechnet werden kann. Hier müssen wir einen Codeabschnitt anzeigen, nämlich ngx_conf_parse() , die hauptsächlich zum Parsen der Konfigurationsdatei nginx.conf verwendet wird. Nach dem Parsen eines Konfigurationselements wird die Definition des Konfigurationselements in allen Modulen gefunden. Wenn das Konfigurationselement gefunden wird, wird versucht, die dem Konfigurationselement entsprechende Struktur abzurufen, und die vom Konfigurationselement angegebene Methode wird aufgerufen, um die Daten des Konfigurationselements zu parsen. Wenn Sie versuchen, hier die Struktur abzurufen, die dem Konfigurationselement entspricht, müssen Sie den obigen Offset verwenden. So erhalten Sie dieses Konfigurationselement:
// Suchen Sie das Konfigurationsobjekt. Die Konstante NGX_DIRECT_CONF wird einfach verwendet, um die Adressierungsmethode des Konfigurationsspeicherbereichs anzugeben. Sie wird nur im Kernmodul verwendet, wenn (cmd->type & NGX_DIRECT_CONF) {
conf = ((void **) cf->ctx)[cf->cycle->modules[i]->index];
// Die Konstante NGX_MAIN_CONF hat zwei Bedeutungen. Eine ist, dass der Kontext der angegebenen Anweisung der Hauptkontext ist (tatsächlich bezieht er sich immer noch auf das Kernmodul).
// Die zweite besteht darin, die Adressierungsmethode des Konfigurationsspeicherbereichs anzugeben.
} sonst wenn (cmd->Typ & NGX_MAIN_CONF) {
conf = &(((void **) cf->ctx)[cf->cycle->modules[i]->index]);
// Mit Ausnahme des Kernmoduls verwenden andere Modultypen die dritte Konfigurationsadressierungsmethode, d. h., sie übernehmen gemäß dem Wert von cmd->conf// die entsprechende Konfiguration von cf->ctx. Am Beispiel des http-Moduls lauten die optionalen Werte von cf->conf NGX_HTTP_MAIN_CONF_OFFSET,
// NGX_HTTP_SRV_CONF_OFFSET, NGX_HTTP_LOC_CONF_OFFSET,
// Entsprechend den drei HTTP-Konfigurationsebenen „http{}“, „server{}“ und „location{}“.
// Die Hauptfunktion dieser if-Beurteilung besteht darin, dass der Typ von cf->ctx ngx_http_conf_ctx_t ist und der Hauptwert von cmd->conf optional ist // NGX_HTTP_MAIN_CONF_OFFSET, NGX_HTTP_SRV_CONF_OFFSET, NGX_HTTP_LOC_CONF_OFFSET,
// Sie können sehen, dass die Attribute von ngx_http_conf_ctx_t main_conf, srv_conf und loc_conf sind.
// Tatsächlich muss hier berechnet werden, in welchem der drei Arrays das aktuelle Konfigurationsobjekt gespeichert ist. Nehmen Sie als Beispiel die Anweisung default_type.
// Die ngx_command_t-Konfiguration lautet:
// {ngx_string("Standardtyp"),
// NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_CONF_TAKE1,
// ngx_conf_set_str_slot,
// NGX_HTTP_LOC_CONF_OFFSET,
// Offset von (ngx_http_core_loc_conf_t, Standardtyp),
// NULL},
// Wie Sie sehen können, ist der Wert seines conf-Attributs NGX_HTTP_LOC_CONF_OFFSET, was bedeutet, dass es im loc_conf-Array gespeichert ist.
// Der Elementtyp im Array ist ngx_http_core_loc_conf_t, daher können Sie sehen, dass das folgende ngx_command_t
// Der Wert des Offset-Attributs wird als offsetof(ngx_http_core_loc_conf_t, default_type) angegeben,
// So wird das Attribut default_type in der Struktur ngx_http_core_loc_conf_t berechnet.
// Durch den folgenden if-Beurteilungsschritt confp = *(void **) ((char *) cf->ctx + cmd->conf); können wir // berechnen, ob sich die aktuell verwendete Struktur in main_conf, srv_conf befindet
// und loc_conf in welchem Array und durch den zweiten Schritt conf = confp[cf->cycle->modules[i]->ctx_index];
// Die Berechnung kann die spezifische Position der Struktur im Array berechnen und die Strukturdaten abrufen.
// Beachten Sie, dass diese Berechnungsmethode nur auf die Konfigurationselementerfassung des http-Moduls anwendbar ist, da nur die Konfigurationsstruktur des http-Moduls vom Typ // ngx_http_conf_ctx_t ist} else if (cf->ctx) {
confp = *(void **) ((char *) cf->ctx + cmd->conf);
wenn (confp) {
conf = confp[cf->Zyklus->Module[i]->ctx_index];
}
} Hier müssen wir uns auf den letzten else if -Zweig konzentrieren, der zeigt, wie das http-Modul basierend auf der Definition des Konfigurationselements den Speicherort der dem Konfigurationselement entsprechenden Struktur berechnet. Die folgende Abbildung zeigt die Gesamtstruktur einschließlich der HTTP-Blockkonfiguration: 
2. Speicherung von Serverblöcken Wie oben erwähnt, kann die Struktur ngx_http_conf_ctx_t verwendet werden, um alle Konfigurationselemente im http-Block zu speichern. Wie werden also die Konfigurationselemente im Serverblock gespeichert? Es wird hauptsächlich in main_conf des Moduls ngx_http_core_module gespeichert, also in der Struktur ngx_http_core_main_conf_t main_conf[0] entspricht. Die Struktur besitzt ein Attribut servers und der Typ dieses Attributs ist ngx_array_t , also ein Array. Das heißt, unter jedem HTTP-Konfigurationsblock entspricht jeder Serverkonfigurationsblock einem Element des servers Arrays, und der Elementtyp des Arrays stimmt mit dem des HTTP-Blocks überein, der immer noch ngx_http_conf_ctx_t ist. Der Unterschied besteht jedoch darin, dass das aktuelle Konfigurationselement im Serverblock oder Standortblock und nicht nur im http-Block verfügbar sein muss. Der Typ des Konfigurationselements muss einer der oben genannten NGX_HTTP_SRV_CONF_OFFSET und NGX_HTTP_LOC_CONF_OFFSET sein und kann nicht NGX_HTTP_MAIN_CONF_OFFSET sein. Obwohl die Konfigurationsstruktur, die jedem Serverkonfigurationsblock entspricht, immer noch ngx_http_conf_ctx_t ist, verfügt sein main_conf Array daher nicht über entsprechende Konfigurationselemente, sondern kann nur Konfigurationselemente vom http-Block erben. Da es sich um eine Vererbung handelt, behandelt nginx dies, indem der Zeiger des Arrays direkt auf main_conf Array von ngx_http_conf_ctx_t zeigt, das dem http-Block entspricht. Nachfolgend sehen Sie ein Diagramm der Konfiguration zweier Serverblöcke: 
Dieses Diagramm sieht etwas kompliziert aus, ist es aber nicht. Gemäß der Konfigurationsblockaufteilung speichert ngx_http_conf_ctx_t die Konfiguration des http-Blocks und die beiden ngx_http_conf_ctx_t darunter speichern die Konfiguration der beiden Serverblöcke. Der Zwischenreferenzprozess wird über ngx_http_core_main_conf_t.servers ausgeführt, die dem ngx_http_core_module -Modul des http-Blocks entsprechen. Zu beachten ist, dass in der obigen Serverblockkonfiguration main_conf -Zeiger auf main_conf Attribut des entsprechenden ngx_http_conf_ctx_t im http-Block verweist. 3. Speichermethode des Standortblocks Für die Speicherung von Standortblöcken lautet die Speicherstruktur weiterhin ngx_http_conf_ctx_t . Da sich das aktuelle Konfigurationselement im Standortblock befindet, ist sein Typ definitiv nicht NGX_HTTP_MAIN_CONF_OFFSET und NGX_HTTP_SRV_CONF_OFFSET . Das heißt, die durch Analysieren des Standortkonfigurationselements erhaltenen Daten müssen im Array loc_conf gespeichert werden. Daher zeigen main_conf und srv_conf in der dem Standortblock entsprechenden Struktur ngx_http_conf_ctx_t wie der Serverblock auf main_conf des http-Blocks, in dem sich der aktuelle Standort befindet, und srv_conf -Array des Serverblocks, in dem er sich befindet. Darüber hinaus gibt es unter einem Serverblock mehrere Standortblöcke. In Bezug auf die Speicherstruktur sind diese Standortblöcke in Form von Warteschlangen organisiert. Ähnlich wie der Serverblock wird diese Warteschlange in loc_conf[0] von ngx_http_conf_ctx_t gespeichert, entsprechend dem Serverblock, in dem sie sich befindet. Der Strukturtyp von loc_conf[0] ist hier ngx_http_core_loc_conf_s , das ein Attribut locations vom Typ ngx_queue_t besitzt, welches die Standortwarteschlange ist. Abschließend ist zu beachten, dass locations hier mehr als nur mehrere Standortblöcke unter dem Serverblock darstellt, da unter dem Standortkonfigurationsblock weiterhin mehrere Standortblöcke konfiguriert werden können und so rekursiv weiter. Der Typ dieser Unterstandortblöcke ist tatsächlich ngx_http_core_loc_conf_s , sodass sie auch durch locations dargestellt werden können. Nachfolgend sehen Sie eine schematische Darstellung der Struktur zum Hinzufügen des Standortkonfigurationsblocks: 
Die Abbildung zeigt eine Situation, in der zwei Standorte parallel organisiert sind. main_conf und srv_conf verweisen jeweils auf main_conf des HTTP-Blocks und srv_conf des Serverblocks, in dem sich der aktuelle Standortblock befindet. Die den beiden Standortblöcken entsprechenden Strukturen sind in ngx_http_core_loc_conf_t in einer Warteschlange organisiert. 4. Zusammenfassung Dieser Artikel beginnt mit der ngx_cycle_t -Struktur und stellt vor, wie die Konfigurationselemente des http-Blocks in ngx_cycle_t gespeichert werden. Außerdem werden die Speichermethoden des http-Blocks, des Serverblocks und des Standortblocks sowie deren Organisation untereinander vorgestellt. 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:- Allgemeine Anweisungen zur Konfiguration des Nginx-HTTP-Moduls
|