Die OpenResty-Distribution für Nginx

Kirill Kurashov, 123RF

Agentenkoffer

Event-basierte Verarbeitung von Requests macht Nginx zu einem flinken Webserver. Mit den OpenResty-Paketen wird daraus ein schneller Application-Server auf Basis der Skriptsprache Lua.
Sicher verstaut - Deduplizierung spart Platz, Cloud-Backup für Windows, Areca sichert kostenlos. ADMIN 01/14 stellt Backups für Profis mit und ohne Cloud ... (mehr)

In der Open-Source-Welt gibt es täglich so viele neue, interessante Projekte, nach denen es sich lohnt, Ausschau zu halten. Meist sind es Projekte US-amerikanischen Ursprungs, denen die große Aufmerksamkeit zuteil wird, während Projekte aus anderen Ländern zum Teil eher unbekannt sind. Das können deutsche Projekte sein, aber vor allem französische oder chinesische Projekte sind hierzulande oft unbekannt. Ein Beispiel dafür ist der chinesische Fork des Webservers Nginx (der ja seinerseits russischen Ursprungs ist), den wir in [1] vorgestellt haben. Ein weiteres Projekt aus dem Umfeld des "chinesischen Amazon" Taobao ist die Nginx-Distribution OpenResty [2] , die fast im Alleingang von Yichun "Agent" Zhang entwickelt wurde. Er hat in OpenResty den Nginx-Server mit vielen nützlichen Modulen gebündelt, die er zum Großteil selbst geschrieben hat und die aus Nginx einen superschnellen Web-Application-Server machen.

Den Großteil von OpenResty machen Module für die Skriptsprache Lua aus, die als eingebettete Sprache wegen ihres geringen Ressourcenverbrauchs und ihrer guten Performance beliebt ist. Auch der Apache-Webserver hat mittlerweile das in ADMIN 03/2012 vorgestellte Mod-Lua in die Kerndistribution aufgenommen [3] . Weitere Beispiele für die Beliebtheit von Lua und eine Einführung in die Sprache sind im Programmieren-Teil dieses Hefts zu finden. Die OpenResty-Module erlauben es, schon in den Konfigurationsdateien Lua-Anweisungen zu verwenden. Das erlaubt komplexe und dynamische Konfigurationen, mit denen sich zum Beispiel Web-Services implementieren lassen. Mitgeliefert werden etwa Module zur Anbindung an Memcache und Datenbanken wie MySQL / Drizzle , PostgreSQL und Redis .

Lua inklusive

Mit OpenResty können Lua-Skripts in alle Phasen der Verarbeitung eines HTTP-Requests eingreifen, sie verändern, Antworten erstellen und Header verändern. Dies alles passiert in recht hoher Geschwindigkeit, sodass die Kombination Lua und Nginx, namentlich OpenResty, unter den ersten Plätzen der Web-Framework-Benchmarks von TechEmpower zu finden ist ( Abbildung 1 ). Der Grund dafür liegt in der Event-basierten Verarbeitung von Requests, die Nginx auszeichnet, und die sich dank OpenResty auch mit Lua-Code nutzen lässt. Noch schneller geht es mit dem Lua-Just-in-Time-Compiler (LuaJIT), der Teil von OpenResty ist.

Abbildung 1: OpenResty rangiert unter den ersten Plätzen der TechEmpower-Benchmarks.

Den gängigen Linux-Distributionen liegt OpenResty nicht bei, Sie müssen es also aus dem Quellcode selbst übersetzen. Dafür müssen einige Pakete und Bibliotheken installiert sein, nämlich Perl 5.6.1 oder neuer, Libreadline, Libpcre und LibSSL. Dann laden Sie das Quellcode-Paket von der OpenResty-Website herunter, entpacken es und führen »./configure« aus, am besten mit der Option »--with-luajit« . Per Default sind außerdem die Module für die Drizzle-Datenbank, PostgreSQL und Iconv ausgeschaltet. Aktivieren Sie sie mit den passenden Configure-Optionen, wenn Sie sie brauchen. Mehr verrät »./configure --help« . Installiert werden die Binärdateien und die Module mit »make install« . Allerdings gibt es kein »make install« , weshalb es sich empfiehlt, zum Beispiel das Checkinstall-Paket zu installieren und dann OpenResty mit »checkinstall make install« zu installieren. Die installierten Dateien lassen sich dann über den Paketmanager der Distribution wieder entfernen.

Manuelle Installation

Per Default werden die Nginx-Dateien in »/usr/local/openresty« installiert. Wer das nicht will, setzt mit der Configure-Option »--prefix« ein anderes Verzeichnis. Die Default-Einstellung ist aber nicht schlecht, denn sie kollidiert nicht mit eventuell installierten Nginx-Paketen einer Linux-Distribution. Bleibt noch, den Nginx-Server beim Booten zu starten, was die beiden Konfigurationsdateien in Listing 1 (Upstart) und Listing 2 (Systemd) übernehmen. Ein Aufruf von »nginx -t« überprüft die Konfiguration, bevor der Serverprozess startet. Im Fehlerfall verschafft »nginx -V« einen Überblick über die vorhandenen Module.

Listing 2

/lib/systemd/system/nginx.service

01 [Unit]
02 Description=OpenResty Stack for Nginx
03 After=syslog.target network.target remote-fs.target nss-lookup.target
04
05 [Service]
06 Type=forking
07 PIDFile=/var/run/nginx.pid
08 ExecStartPre=/usr/local/openresty/nginx/sbin/nginx -t
09 ExecStart=/usr/local/openresty/nginx/sbin/nginx
10 ExecReload=/bin/kill -s HUP $MAINPID
11 ExecStop=/bin/kill -s QUIT $MAINPID
12 PrivateTmp=true
13
14 [Install]
15 WantedBy=multi-user.target

Listing 1

/etc/init/openresty.conf

01 # openresty
02
03 description "nginx openresty stack"
04 author "Oliver Frommel <ofrommel@domain.com>"
05
06 start on (filesystem and net-device-up IFACE=lo)
07 stop on runlevel [!2345]
08
09 env DAEMON=/usr/local/openresty/nginx/sbin/nginx
10 env PID=/var/run/nginx.pid
11
12 expect fork
13 respawn
14 respawn limit 10 5
15
16 pre-start script
17         $DAEMON -t
18         if [ $? -ne 0 ]
19                 then exit $?
20         fi
21 end script
22
23 exec $DAEMON

Übrigens gibt es auch Module für einschlägige Software zum Konfigurationsmanagement, mit denen sich OpenResty auf Servern deployen lässt. So liegen auf Github einige Module für Puppet, ein Chef-Kochrezept ist direkt auf der Opscode-Website zu finden. Das Chef-Modul wird gut gepflegt und wurde zuletzt Anfang November 2013 aktualisiert.

Im einfachsten Fall lässt sich nun Lua-Code über das Schlüsselwort »content_by_lua« direkt in die Konfigurationsdateien einbetten, etwa so:

content_by_lua '
    ngx.say("<p>test</p>")
';

Aus einer Datei liest Nginx den Lua-Code über »content_by_lua_file« . Analog dazu übernimmt Lua auch das Umschreiben von Requests (Rewrite) oder die Authentifizierung. Die dafür vorgesehenen Anweisungen, die Lua-Code aus einer Datei laden, heißen »rewrite_by_lua« und »content_by_lua« . Dabei lädt der Webserver normalerweise den Lua-Code nur einmal ein, was klarerweise den Overhead reduziert. Abschalten lässt sich dies, etwa bei der Entwicklung von Skripts, indem man »lua_code_cache« auf »off« setzt.

Im Prinzip geht es sogar auch ganz ohne Lua-Code, wie ein Beispiel von Richard Nyström zeigt [5] , der einen Web-Service nur mit SQL-Anweisungen in der Nginx-Konfiguration realisiert. Zum Beispiel liefert der folgende Ausschnitt der Konfiguration bei einem Get-Request alle Artikel einer Datenbank zurück:

postgres_query  HEAD GET "SELECT * FROM articles";

Oft liegen die interessanten Daten nicht direkt auf dem Webserver, sondern sind auf andere Rechner ausgelagert, wo zum Beispiel ein Verzeichnisdienst, eine Datenbank oder Ähnliches laufen. OpenResty unterstützte solche Serviceorientierten Architekturen (SOA) über sogenannte Subrequests. Ein eingehender HTTP-Requests löst also weitere Requests aus, die fehlende Daten einholen, entweder von anderen Rechnern oder von Diensten auf demselben Server, auf dem auch Nginx läuft. Ein Beispiel dafür ist das Auth-Request-Modul, das Subrequests zur Authentifizierung verwendet. So lässt sich der Zugriffsschutz modular gestalten und verschiedene Dienste miteinander verbinden:

location /private/ {
  auth_request /auth;
   ...
}

Selbst parallele Subrequests können abgesetzt werden, wenn man den Aufruf »capture_multi« verwendet. Auf einer niedrigeren Ebene angesiedelt ist ein Interface, um direkt mit Netzwerk-Sockets zu arbeiten. Es entspricht der TCP-API von Lua, arbeitet aber per Default nichtblockierend.

Auch Realtime-Webanwendungen sind mit OpenResty kein Problem. Sie lassen sich zum Beispiel mit dem Websocket-Support verwenden, den Nginx in der stabilen Version 1.4.0 hinzugewonnen hat [6] . Allerdings wird Nginx damit nur zum Websocket-Proxy. Um die Verarbeitung der Daten muss sich jemand anders kümmern. Mit OpenResty kann das zum Beispiel ein Lua-Modul übernehmen. Weil Socket-Programmierung damit relativ unaufwendig ist, braucht es dafür nur wenige Zeilen Code. Wie das geht, hat Aapo Talvensaari in seinem Blog [7] demonstriert.

Ein recht interessantes Modul, das sich für Debugging oder die Entwicklung von Webanwendungen oder -diensten gut eignet, ist »ngx_echo« , das das Konfigurationsvokabular um Shell-artige Anweisungen wie »echo« , »sleep« , »time« und »exec« erweitert. Damit lassen sich URLs einrichten, um Clients zu testen, ohne dass auf dem Server gleichzeitig fehleranfälliger Code geschrieben werden muss. Das folgende Beispiel zeigt eine Anwendung:

location /echodelay {
        echo hello;
        echo_flush;
        echo_sleep 2.5;
        echo world;
      }

Zuerst gibt der Codeblock den String »hello« aus, der durch das Leeren des Output-Puffers mit »echo_flush« sofort sichtbar wird. Danach wartet der Server 2,5 Sekunden lang, bevor er mit der Ausgabe von »world« weitermacht.

Die Beschreibung der vielen Möglichkeiten, die OpenResty über die Programmierung mit Lua bietet, würde den Rahmen des Artikels sprengen. Tabelle 1 gibt aber einen Überblick über alle mitgelieferten Module.

Tabelle 1

OpenResty-Module

Modul

Funktion

ArrayVarNginxModule

Array-Variablen für Nginx-Konfigurationsdateien

AuthRequestNginxModule

Authentifizierung mit Subrequests

CoolkitNginxModule

Sammlung kleiner Nginx-Addons

DrizzleNginxModule

Anbindung an Drizzle- und MySQL-Datenbank

EchoNginxModule

Shell-artige Utilities für Debugging

EncryptedSessionNginxModule

Verschlüsselte Session-Daten

FormInputNginxModule

Verarbeitung von Formularen in Nginx-Konfiguration

HeadersMoreNginxModule

Erweiterte Header-Verarbeitung

IconvNginxModule

Konvertierung von Zeichensätzen

StandardLuaInterpreter

Standard-Lua-Interpreter

MemcNginxModule

Memcache-Protokoll

Nginx

Nginx-Distribution

NginxDevelKit

Nginx-SDK

LuaCjsonLibrary

Schnelles JSON-Modul für Lua

LuaJIT

Just-in-Time-Compiler für Lua

LuaNginxModule

Lua-Modul für Nginx

LuaRdsParserLibrary

Parser für Resty-DBD-Stream von Datenbankmodulen

LuaRedisParserLibrary

Parser für Redis-Antworten

LuaRestyDNSLibrary

DNS-Bibliothek

LuaRestyLockLibrary

Nichtblockierende Mutex-Locks

LuaRestyMemcachedLibrary

Treiber für Memcache

LuaRestyMySQLLibrary

Treiber für MySQL

LuaRestyRedisLibrary

Treiber für Redis

LuaRestyStringLibrary

String-Bibliothek

LuaRestyUploadLibrary

Bibliothek für HTTP-Uploads

LuaRestyWebSocketLibrary

Bibliothek für Websockets

PostgresNginxModule

Anbindung an PostgreSQL

RdsCsvNginxModule

Konvertiert Resty-DBD-Streams ins CSV-Format

RdsJsonNginxModule

Konvertiert Resty-DBD-Streams nach JSON

RedisNginxModule

Redis-Modul, liefert verarbeitete Antworten

Redis2NginxModule

Redis-Modul, liefert unverarbeitete Antworten

SetMiscNginxModule

Diverse Einstellungen (MD5, JSON, …)

SrcacheNginxModule

Transparentes Caching

XssNginxModule

Support für Cross-Site-Ajax-Requests

Ähnliche Artikel

comments powered by Disqus
Einmal pro Woche aktuelle News, kostenlose Artikel und nützliche ADMIN-Tipps.
Ich habe die Datenschutzerklärung gelesen und bin einverstanden.

Konfigurationsmanagement

Ich konfiguriere meine Server

  • von Hand
  • mit eigenen Skripts
  • mit Puppet
  • mit Ansible
  • mit Saltstack
  • mit Chef
  • mit CFengine
  • mit dem Nix-System
  • mit Containern
  • mit anderer Konfigurationsmanagement-Software

Ausgabe /2023