Ressourcenlimits und Health Checks
Auf einem gemeinsam genutzten Rechner reicht ein einziger außer Kontrolle geratener Prozess. Ein Queue-Worker in einer Endlosschleife oder ein Node-Prozess, der Speicher verliert, zieht alle anderen Projekte mit nach unten. Im Bereich Ressourcen eines Projekts ziehst du die Grenze.
Limits gibt es für zwei Gruppen. Anwendungscontainer sind Webserver, PHP, Node.js, Python, Go,
Ruby, Java, .NET und jeder Worker; Dienste sind Datenbank, Redis, Memcached, Mailpit, RabbitMQ, die
Suchmaschinen und der Objektspeicher. Für jede Gruppe legst du ein CPU-Limit in Kernen fest
(etwa 1.5) und ein Speicherlimit, in GiB, solange du die Einheit neben dem Feld nicht auf MiB
umstellst.
Leicht zu übersehen: Docker begrenzt Container einzeln, die Werte gelten also für jeden Container der Gruppe und nicht für die Gruppe insgesamt. Ein Projekt mit PHP, Node.js und zwei Workern darf zusammen das Vierfache des Anwendungslimits nutzen.
Dazu kommt ein Limit für Prozesse pro Container, standardmäßig 4096. Das stoppt Fork-Bomben und Worker-Pools, die immer neue Kindprozesse starten, und es gilt für jeden Container, auch wenn du sonst nichts einstellst. Bleibt ein Feld leer, gibt es kein Limit - so startet jedes Projekt. OpenSearch braucht mindestens 1,5 GiB, darunter solltest du dort nicht gehen. Einem Java-Projekt würde ich für die Anwendungscontainer etwa 2 GiB geben: Beim Entwickeln wollen der Daemon des Build-Tools, die JVM der Anwendung und ein Testlauf jeweils ihren Teil, und ein Gradle-Testlauf unter 1 GiB kann den Dev-Server mit in den Abgrund reißen.
Änderungen greifen bei laufenden Containern sofort. Die eine Ausnahme ist das komplette Entfernen
eines CPU- oder Speicherlimits: Docker kann ein Limit nicht im laufenden Betrieb aufheben, deshalb
werden die betroffenen Container neu erstellt. Die Karte zeigt dir CPU und Speicher jedes
laufenden Containers neben seinem Limit. Java tanzt hier aus der Reihe: Eine JVM legt ihren Heap
einmal beim Start fest. Senkst du das Limit eines laufenden Projekts, starte es also neu, sonst
beendet der Kernel die JVM, statt dass Java einen OutOfMemoryError wirft.
Stößt ein Container an sein Speicherlimit, beendet der Kernel einen Prozess darin. Ist das der Hauptprozess, startet der Container neu; es kann aber auch ein Kind sein, etwa ein php-fpm-Worker. So oder so zeigt Envoryx einen Tag lang eine Warnung am Projekt („php ran out of memory at 14:03 (limit 512 MiB)“) und schickt dir eine Benachrichtigung. Meist passiert das binnen Sekunden. Manche Docker-Hosts melden so ein Beenden nicht als Ereignis; dort findet Envoryx es bei seiner nächsten Messung im cgroup-v2-Zähler des Containers, und die Warnung kann bis zu einer Minute dauern.
Limits gehören auch zur envoryx.yml (limits:), siehe
Umgebung und envoryx.yml.
Ressourcenverlauf
Abschnitt betitelt „Ressourcenverlauf“Einmal pro Minute notiert Envoryx, was jeder laufende Projekt-Container verbraucht: CPU, Speicher, Netzwerkverkehr und Festplatten-I/O. Einmal pro Stunde misst es außerdem, wie viel Platz jedes Projekt belegt - Volumes, Projektordner und Backups.
Der Bereich Ressourcen zeichnet das alles für die letzte Stunde bis zum letzten Jahr, und wer lieber Zahlen sieht, bekommt jedes Diagramm auch als Tabelle. Das Dashboard listet jedes Projekt mit durchschnittlicher und maximaler CPU- und Speichernutzung, seinem Platzbedarf und einer kleinen CPU-Kurve, das geschäftigste zuerst. Schneller findest du nicht heraus, welches Projekt gerade den Server auffrisst. Wie lange die Werte bleiben, stellst du unter Einstellungen → Aufbewahrung → Ressourcenverlauf ein: 7, 30 oder 90 Tage (Standard) oder ein Jahr.
Health Checks
Abschnitt betitelt „Health Checks“Ein laufender Container heißt noch lange nicht, dass die Anwendung funktioniert. Deshalb richtest
du im Bereich Übersicht eines Projekts einen Health Check ein: einen Pfad wie /health oder
Laravels /up, der mit dem erwarteten Status antworten muss.
Envoryx fragt den Webserver genauso wie der Proxy, mit dem Hostnamen des Projekts - deine Anwendung
sieht also einen ganz normalen Besucher. Weiterleitungen werden nicht verfolgt, und das ist
wichtig: Ein /health, das auf /login umleitet, zählt als Fehlschlag.
Standardmäßig läuft der Check alle 30 Sekunden (alles zwischen 10 Sekunden und einer Stunde geht) und wartet pro Antwort 5 Sekunden. Nach 3 Fehlschlägen in Folge gilt die Anwendung als down. Du bekommst eine Benachrichtigung beim Ausfall und eine, wenn sie wieder da ist. Testen führt den Check einmal aus, auch schon vor dem Speichern. Solange das Projekt gestoppt ist, gerade eine Operation darauf läuft oder sein Anwendungscontainer nicht läuft, macht der Check Pause.
Ein guter Health-Pfad prüft, wovon deine Anwendung wirklich abhängt - Datenbank, Cache, Queue - und antwortet trotzdem schnell.