Reduzieren Sie die Anzahl der Architekturebenen von 5 auf 2


Während ich an mehreren Open-Source-Projekten arbeitete, beschloss ich eines Tages, mein Leben zu vereinfachen, und entwickelte das Upstream-Modul für Nginx, mit dem ich sperrige Schichten mehrschichtiger Architektur entfernen konnte. Es war eine lustige Erfahrung, die ich in diesem Artikel teilen möchte. Mein Code ist hier öffentlich verfügbar: github.com/tarantool/nginx_upstream_module . Sie können es von Grund auf neu abrufen oder das Docker-Image über diesen Link herunterladen: hub.docker.com/r/tarantool/tarantool-nginx .

Auf der Tagesordnung:

  • Einführung und Theorie.
  • Verwendung dieser Technologien.
  • Leistungsbewertung.
  • Nützliche Links.

Einführung und Theorie




So sieht die Standard-Microservice-Architektur aus. Benutzeranforderungen kommen über nginx an den Anwendungsserver. Auf dem Server befindet sich eine Geschäftslogik, mit der Benutzer interagieren.

Der Anwendungsserver speichert den Status von Objekten nicht, daher müssen sie an einem anderen Ort gespeichert werden. Hierfür können Sie Datenbanken verwenden. Vergessen Sie nicht den Cache, der die Latenz verringert und eine schnellere Bereitstellung von Inhalten ermöglicht.

Teilen Sie es in Schichten:

1. Schicht - Nginx.
2. Schicht - Anwendungsserver.
3. Schicht - Cache.
4. Schicht - Datenbank-Proxy. Dieser Proxy ist erforderlich, um die Fehlertoleranz sicherzustellen und eine konstante Verbindung zur Datenbank aufrechtzuerhalten.
Die 5. Schicht ist der Datenbankserver.

Als ich über diese Ebenen nachdachte, fand ich heraus, wie ich einige davon ausschließen konnte. Warum? Viele Gründe. Ich mag einfache verständliche Dinge; Ich mag es nicht, eine große Anzahl verschiedener Systeme bei der Herstellung zu unterstützen. und nicht zuletzt, je weniger Schichten, desto weniger Fehlerstellen. Als Ergebnis habe ich das Tarantool Upstream-Modul unter nginx erstellt, wodurch die Anzahl der Ebenen auf zwei reduziert wurde.



Wie hilft Tarantool, die Anzahl der Schichten zu reduzieren? Die erste Schicht ist Nginx, die zweite, dritte und fünfte Schicht ersetzen Tarantool. Die vierte Schicht, der Datenbank-Proxy, befindet sich jetzt in Nginx. Der Trick ist, dass Tarantool eine Datenbank, ein Cache und ein Anwendungsserver ist, drei in einem. Mein Upstream-Modul verbindet Nginx und Tarantool miteinander und ermöglicht es ihnen, nahtlos ohne die anderen drei Schichten zu arbeiten.



So sieht der neue Microservice aus. Der Benutzer sendet mit dem Tarantool Upstream-Modul eine Anfrage an REST oder JSON RPC in nginx. Das Modul kann direkt mit Tarantool verbunden werden, oder die Last kann auf mehreren Tarantool-Servern ausgeglichen werden. Zwischen nginx und Tarantool verwenden wir ein effizientes Protokoll, das auf MSGPack basiert. Weitere Informationen finden Sie in diesem Artikel .

Sie können diesen Links auch folgen, um Tarantool und das Nginx-Modul herunterzuladen. Ich würde jedoch empfehlen, sie über den Paketmanager Ihrer Distribution oder über das Docker-Image ( docker pull tarantool/tarantool-nginx ) zu docker pull tarantool/tarantool-nginx .

Docker-Images: hub.docker.com/r/tarantool/tarantool

Tarantool NginX Upstream-Modul

Binärpakete : Tarantool - Download

Quellcode: Tarantool

tarantool / nginx_upstream_module

Verwendung dieser Technologien


Hier ist ein Beispiel für eine nginx.conf-Datei. Wie Sie sehen können, handelt es sich hierbei um einen regulären Upstream-Nginx. Hier haben wir tnt_pass , das nginx direkt tnt_pass welchen Pfad das Upstream-Tarantool eingefügt werden soll.

nginx-tnt.conf
 http { # upstream upstream tnt { server 127.0.0.1:3301; keepalive 1000; } server { listen 8081; # gateway location /api/do { tnt_pass_http_request parse_args; tnt_pass tnt; } } } 

Hier sind die Links zur Dokumentation:

nginx.org/en/docs/http/ngx_http_upstream_module.html
github.com/tarantool/nginx_upstream_module/blob/master/README.md

Konfiguriert ein paar Nginx und Tarantool, was dann? Jetzt müssen wir eine Handlerfunktion für unseren Dienst registrieren und in eine Datei einfügen. Ich habe es in die Datei "app.lua" eingefügt.

Hier ist ein Link zur Tarantool-Dokumentation: tarantool.io/en/doc/1.9/book/box/data_model/#index

 -- Bootstrap Tarantool box.cfg { listen='*:3301' } -- Grants box.once('grants', function() box.schema.user.grant('guest', 'read,write,execute', 'universe') end) -- Global variable hello_str = 'Hello' -- function function api(http_request) local str = hello_str if http_request.method == 'GET' then str = 'Goodbye' end return 'first', 2, { str .. 'world!' }, http_request.args end 

Betrachten Sie nun den Lua-Code.

Unsere Box.cfg {} weist Tarantool an, Port 3301 abzuhören, kann jedoch andere Parameter akzeptieren.

Box.once weist Tarantool an, eine Funktion einmal aufzurufen.

function api () ist eine Funktion, die ich bald aufrufen werde. Es nimmt eine HTTP-Anforderung als erstes Argument und gibt ein Array von Werten zurück.

Ich habe diesen Code in einer Datei gespeichert und ihn "app.lua" genannt. Sie können es ausführen, indem Sie einfach die Tarantool-Anwendung starten.

$> tarantool app.lua

Wir rufen unsere Funktion über eine GET-Anfrage auf. Ich benutze dafür "wget". Standardmäßig speichert "wget" die Antwort auf eine Datei. Und um die Daten aus der Datei zu lesen, benutze ich "cat".

 $ wget '0.0.0.0:8081/api/do?arg_1=1&arg_2=2' $ cat do* { “id”:0, # — unique identifier of the request “result”: [ # — is what our Tarantool function returns [“first”], [2], [{ “request”:{“arg_2”:”2",”arg_1":”1"} “1”:”Goodbye world!” }] ]} 

Leistungsbewertung


Die Bewertung wurde anhand von Daten aus der Produktion durchgeführt. Die Eingabe ist ein großes JSON-Objekt. Die durchschnittliche Größe eines solchen Objekts beträgt 2 KB. Einzelner Server, 4-Kern-CPU, 90 GB RAM, Betriebssystem Ubuntu 14.04.1 LTS.

Für diesen Test verwenden wir nur einen Nginx-Worker. Dieser Worker ist ein Balancer mit einem einfachen ROUND-ROBIN-Algorithmus. Es verteilt die Last zwischen den beiden Tarantool-Knoten. Die Last wird mithilfe von Sharding skaliert.

Diese Grafiken zeigen die Anzahl der Lesevorgänge pro Sekunde. Das obere Diagramm zeigt die Verzögerungen (in Millisekunden).



Diese Grafiken zeigen die Anzahl der Schreibvorgänge pro Sekunde. Das obere Diagramm zeigt Verzögerungen (in Millisekunden).



Beeindruckend!

Im nächsten Artikel werde ich ausführlich über REST und JSON RPC sprechen.

Englische Version des Artikels: hackernoon.com/shrink-the-number-of-tiers-in-a-multitier-architecture-from-5-to-2-c59b7bf46c86

Source: https://habr.com/ru/post/de417829/


All Articles