Direkt zum Inhalt

Wie behebe ich OutOfMemory-Fehler in Amazon ECS?

Lesedauer: 5 Minute
0

Meine Amazon Elastic Container Service (Amazon ECS)-Aufgaben haben Probleme mit der Speichernutzung. Oder meine Container werden aufgrund eines OutOfMemory-Fehlers beendet.

Kurzbeschreibung

Wenn du Probleme mit unzureichendem Arbeitsspeicher hast, hält Amazon ECS die Aufgabe an und du erhältst die folgende Fehlermeldung:

„OutOfMemoryError: Container killed due to memory usage“.

Dieses Problem tritt auf, wenn die Prozesse des Containers mehr Speicher verwenden, als du in der Aufgabendefinition zugewiesen hast. Führe die folgenden Maßnahmen zur Problembehandlung durch, um OutofMemory-Probleme zu beheben.

Lösung

Aufgaben identifizieren, die Amazon ECS aufgrund von Speichererschöpfung beendet hat

Gehe wie folgt vor, um Aufgaben zu identifizieren, die Amazon ECS aufgrund von Speichererschöpfung beendet hat:

  1. Überprüfe die angehaltenen Aufgaben auf der Amazon ECS-Konsole.
  2. Suche nach Aufgaben mit den Beendencodes 137 oder 139, die normalerweise auftreten, wenn Amazon ECS speicherbedingte Ausfälle hat.
  3. Wenn du Speicherprobleme feststellst, überprüfe die Container Agent-Protokolle auf Heap-Out-of-Memory-Probleme, die zum Anhalten der Aufgabe geführt haben.

Überwachen und Analysieren der Nutzung des Container-Speichers

Um speicherbezogene Anwendungsprobleme zu beheben, verwende Amazon CloudWatch Logs, um die Aufgaben zu analysieren. Verwende die Amazon ECS- oder die CloudWatch-Konsole, um die Speichernutzung des Services zu überwachen. Richte für containerspezifische Speichermetriken CloudWatch Container Insights mit verbesserter Beobachtbarkeit ein.

Verwende eine benutzerdefinierte Abfrage in CloudWatch Logs Insights, um die Speichernutzung eines Containers im Zeitverlauf zu analysieren.

Beispielabfrage:

stats max(MemoryUtilized) as mem, max(MemoryReserved ) as memreserved by bin (5m) as period, TaskId, ContainerName
| sort period desc
| filter ContainerName like "example-container-name"
| filter TaskId = "example-task-id"

Hinweis: Ersetze example-container-name durch deinen Container-Namen und example-task-id durch deine Aufgaben-ID.

Festlegen der Speicherkontingente in der Amazon ECS-Aufgabe und im Amazon ECS-Container

Auf Aufgabenebene kannst du ein Festplattenkontingent für die gesamte Aufgabe festlegen. Auf Containerebene kannst du die Parameter memoryReservation (memory soft limits) und memory (memory hard limits) verwenden, um Speicher zuzuweisen.

Bevor du die Anwendung bereitstellst, stelle sicher, dass dein Host über ausreichend verfügbaren Speicher verfügt. Aktualisiere dann die Aufgabendefinition mit weichen und harten Speicherkontingenten.

Hinweis: Du kannst den Parameter memoryReservation nur in Linux-Containern verwenden.

Beispiel für eine Aufgabendefinition:

"containerDefinitions": [
    {
        "name": "example-container-name",
        "memory": 1024,
        "memoryReservation": 512
        // ... other container properties
    }
]

Konfigurieren des Austauschs für Container, die einen hohen temporären Speicherbedarf haben

Hinweis: Um die Parameter maxSwap und sharedMemorySize verwenden zu können, müssen die Aufgaben den Amazon Elastic Compute Cloud (Amazon EC2)-Starttyp verwenden.

Wenn es in den Containern zu hohen, temporären Speicherauslastungsspitzen kommt, aktualisiere die Aufgabendefinition, um die Tauschen-Konfiguration zu verwenden. Das Tauschen reduziert OutofMemory-Fehler, die bei hoher Auslastung auftreten. Das Tauschen kann jedoch auch die Anwendung verlangsamen. Nachdem du das Tauschen aktiviert hast, überwache die Leistung der Anwendung.

Speichereinstellungen der Anwendung an das Laufzeit-Framework anpassen

Anwendungen werden möglicherweise angehalten, wenn sie die standardmäßigen Speicherkontingente des Frameworks oder der Laufzeit erreichen, selbst bei verfügbarem Systemspeicher oder erhöhten Containerkontingenten. Überwache die Speichernutzungsmuster der Anwendung, um dieses Problem zu beheben. Identifiziere die Standardspeichereinstellungen des Frameworks oder der Laufzeit und passe dann die Speicherparameter der Aufgabe an die Anforderungen der Anwendung an.

Java-Anwendungen

Die Java Virtual Machine (JVM) erfordert beim Startup eine anfängliche Speicherzuweisung durch das Betriebssystem (OS) und hat ein maximales Speichernutzungskontingent. Weitere Informationen findest du unter The java.lang.OutOfMemoryError error (Der java.lang.OutOfMemoryError-Fehler) auf der Oracle-Website. Verwende JVM-Flags, um die Speicherwerte anzupassen. Führe beispielsweise den folgenden Befehl aus, um -Xms zum Festlegen der anfänglichen Heap-Größe und -Xmx zum Festlegen der maximalen Heap-Größe zu verwenden:

java -Xms512m -Xmx2048m -jar your-app.jar

Um die detaillierte Garbage Collection (GC)-Protokollierung zu aktivieren, füge dem Java-Befehl das folgende JVM-Argument hinzu:

-verbose:gc -Xlog:gc*:file=log_filename:time,uptime:filecount=num_files,filesize=file_sizem

Weitere Informationen findest du unter Garbage Collection Logs (Garbage Collection-Protokolle) auf der Oracle-Website.

Verwende für erweiterte Speicherdiagnosen jcmd oder jmap, um Heap-Sicherungen und Analysetools wie JDK Mission Control oder VisualVM zu generieren. Weitere Informationen findest du unter Diagnostic data (Diagnosedaten) und Analysis tools (Analysetools) auf der Oracle-Website.

Node.js-Anwendungen

Verwende das folgende v8.getHeapStatistics()-Modul, um das Standard-Heap-Speicherkontingent zu überprüfen:

const v8 = require('v8');
console.log(v8.getHeapStatistics());

Weitere Informationen findest du unter v8.getHeapStatistics() auf der Node.js-Website.

Um das Heap-Größenkontingent zu erhöhen, verwende den Parameter**--max-old-space-size**, wenn du die Anwendung ausführst:

node --max-old-space-size=4096 app.js

Hinweis: Der vorhergehende Befehl legt ein Heap-Kontingent von 4 Gigabyte (GB) fest. Die Standardgröße des Heap-Speichers kann in den verschiedenen Versionen von Node.js variieren. Weitere Informationen findest du unter --max-old-space-size=SIZE (in MiB) auf der Node.js-Website.

Um die Garbage Collection zu verfolgen, füge dem Knoten-Prozess das folgende Flag hinzu:

node --trace-gc server.js

Weitere Informationen findest du unter Tracing Garbage Collection (Verfolgen von Garbage Collection) auf der Node.js-Website.

Verwende für eine ausführliche Speicherdiagnose die in Node.js V8 integrierten Profiler wie --heap-prof, um Heap-Snapshots zu erstellen. Oder verwende --heapsnapshot-signal, um Linux-Signale zum Erstellen von Heap-Snapshots zu verwenden. Weitere Informationen findest du unter --heap-prof und Using heap snapshot auf der Node.js-Website.

Skalieren des Service, um die Speichernutzung auf Service-Ebene zu optimieren

Um die Speichernutzung auf Service-Ebene zu optimieren, solltest du die Ressourcenzuweisung überwachen und anpassen, um Aufgaben auf der Grundlage von Speichernutzungsmustern zu skalieren. Berechne den Gesamtspeicher, den die Service-Aufgaben verwenden. Passe dann den gewünschten Aufgabenwert im Service manuell an deinen Speicherbedarf an.

Oder verwende Richtlinien zur Serviceskalierung, die auf Metriken der Speichernutzung basieren. Konfiguriere die Skalierungsrichtlinien mit Schwellenwerten für die Auf- und Abskalierung.

Vermeiden zukünftiger OutofMemory-Fehler

Um zukünftige OutofMemory-Fehler zu vermeiden, führe einen Belastungstest für den Container auf einem Host oder Server durch, um den Speicherbedarf der Anwendung zu ermitteln. Verwende Docker-Container-Statistiken, um die Speichernutzung der Container beim Testen zu überwachen. Weitere Informationen findest du unter docker container stats (Docker-Container-Statistiken) auf der Docker-Website.

Gehe wie folgt vor, um die Container-Konfiguration zu aktualisieren:

  • Verwalte die Datenstrukturen.
  • Vermeide eine unnötige Objekterstellung.
  • Implementiere das Caching.
  • Verwende effiziente Algorithmen, um den Speicherbedarf zu reduzieren.

Ähnliche Informationen

Wie behebe ich Probleme, wenn Amazon-ECS-Aufgaben angehalten werden oder nicht gestartet werden, wenn mein Container beendet wird?

AWS OFFICIALAktualisiert vor 2 Jahren