Häufige Jenkins-Leistungsengpässe und wie man sie behebt

Kämpfen Sie mit einer langsamen Jenkins-Instanz? Dieser umfassende Leitfaden taucht in häufige Jenkins-Leistungsengpässe ein, einschließlich Speicherlecks, Festplattenplatzproblemen und übermäßiger Protokollierung. Lernen Sie, Symptome zu identifizieren, Ursachen zu verstehen und umsetzbare Lösungen wie JVM-Tuning, intelligentes Build-Verlaufsmanagement, Log-Optimierung und effiziente Pipeline-Programmierung zu implementieren. Entdecken Sie wichtige Überwachungswerkzeuge und Best Practices, um Ihre CI/CD-Pipelines reibungslos am Laufen zu halten, schnellere Builds, eine reaktionsschnelle Benutzeroberfläche und einen insgesamt effizienteren Softwarebereitstellungsprozess zu gewährleisten.

Häufige Jenkins-Leistungsengpässe und wie man sie behebt

Eine langsame Jenkins-Instanz hat normalerweise nicht eine Ursache. Die Benutzeroberfläche fühlt sich schwer an, Builds warten in der Warteschlange, Agents trennen die Verbindung, Protokolle lassen sich ewig öffnen, und jemand sagt: "Jenkins ist schon wieder down." Hinter dieser Beschwerde steckt oft einer von ein paar gewöhnlichen Engpässen: Controller-Heap-Druck, langsame Festplatte, überlastete Agents, Plugin-Probleme, schlechtes Pipeline-Verhalten oder Netzwerkverzögerungen zu Quellcodeverwaltung und Artefaktsystemen.

Der schnellste Weg, Jenkins-Leistung zu beheben, ist, Controller-Probleme von Build-Problemen zu trennen. Wenn die Jenkins-Benutzeroberfläche, die Warteschlange und die Job-Seiten auch dann langsam sind, wenn keine Builds laufen, beginnen Sie mit dem Controller. Wenn die Benutzeroberfläche in Ordnung ist, aber Builds zu lange dauern, beginnen Sie mit Agents, Workspaces, Caches und externen Systemen.

Controller-Speicher und Garbage Collection

Der Jenkins-Controller ist ein Java-Prozess. Er benötigt genügend Heap für Job-Konfiguration, Plugins, Build-Metadaten, Warteschlangenzustand und Webanfragen. Wenn der Heap zu klein ist, verbringt der Controller zu viel Zeit mit der Garbage Collection. Wenn ein Plugin Speicher leckt oder zu viele Daten im Speicher speichert, kann eine Erhöhung des Heaps den nächsten Vorfall nur verzögern.

Zu den Symptomen gehören eine langsame Benutzeroberfläche, lange Pausen, OutOfMemoryError, häufige Agent-Trennungen oder Verzögerungen in der Build-Warteschlange, die nicht zu den verfügbaren Executoren passen.

Überprüfen Sie zuerst den Prozess und die Protokolle:

ps -o pid,rss,vsz,etime,cmd -C java
journalctl -u jenkins --since "2 hours ago" | grep -Ei 'OutOfMemory|GC overhead|heap|killed'

Für einen moderaten Controller kann ein Heap von 2 bis 4 GB ausreichen. Viel genutzte Installationen benötigen möglicherweise mehr. Setzen Sie den Heap nicht blind auf den Großteil des Arbeitsspeichers der Maschine. Das Betriebssystem benötigt immer noch Speicher für Dateisystem-Cache, Prozess-Overhead und Überwachungs-Agents.

Typische Service-Optionen sehen so aus:

JENKINS_JAVA_OPTS="-Xms1g -Xmx4g -XX:+UseG1GC"

Nachdem Sie die JVM-Optionen geändert haben, starten Sie Jenkins während eines Wartungsfensters neu und beobachten Sie das Verhalten unter normaler Last. Wenn der Speicher über Tage stetig ansteigt und sich nie stabilisiert, nehmen Sie einen Heap-Dump und überprüfen Sie kürzlich aktualisierte oder installierte Plugins. Halten Sie Plugins aktuell, vermeiden Sie jedoch die Aktualisierung einer großen Plugin-Menge ohne einen Rollback-Plan.

Festplattenspeicher und Festplatten-I/O

Jenkins verwendet ständig die Festplatte. JENKINS_HOME speichert Job-Konfiguration, Build-Aufzeichnungen, Fingerabdrücke, Plugin-Daten, Geheimnisse, Protokolle und manchmal zu viele Artefakte. Agents verwenden die Festplatte für Workspaces, Abhängigkeits-Caches, Docker-Layer, Testberichte und temporäre Dateien.

Eine volle Festplatte ist offensichtlich. Eine langsame Festplatte ist ärgerlicher, weil nichts kaputt aussieht; alles wartet nur.

Überprüfen Sie sowohl Kapazität als auch Latenz:

df -h
du -sh /var/lib/jenkins/* 2>/dev/null | sort -h | tail
iostat -xz 1

Wenn %util und await-Zeiten während Builds hoch sind, ist die Festplatte ein Engpass. Häufige Lösungen sind das Verschieben von Workspaces auf schnelleren Speicher, das Bereinigen alter Docker-Layer, die Reduzierung der Artefakt-Aufbewahrung und das Stoppen von Jobs, die ganze Verzeichnisse archivieren, wenn nur Berichte oder Pakete benötigt werden.

Legen Sie Build-Bereinigungsrichtlinien für Jobs fest:

options {
  buildDiscarder(logRotator(numToKeepStr: '30', artifactNumToKeepStr: '10'))
}

Seien Sie vorsichtig bei manuellen Bereinigungen in JENKINS_HOME. Löschen Sie keine zufälligen XML-Dateien oder Plugin-Verzeichnisse, während Jenkins läuft. Verwenden Sie Jenkins-Aufbewahrungseinstellungen, plugin-spezifische Bereinigungswerkzeuge und Backups.

Zu viel Arbeit auf dem Controller

Eine der schädlichsten Konfigurationen ist das Ausführen von Builds auf dem Controller. Der Controller sollte nicht kompilieren, Tests ausführen, Docker-Images erstellen oder große Checkouts durchführen.

Setzen Sie Controller-Executoren in den meisten Installationen auf 0. Führen Sie Builds auf Agents aus. Wenn Sie bereits Controller-Builds ausführen, verschieben Sie sie schrittweise und achten Sie auf versteckte Annahmen wie lokale Tool-Pfade, Credential-Bindungen oder Dateien, die nur auf dem Controller existieren.

Überprüfen Sie auch Pipelines auf Controller-intensive Groovy-Codes. Pipeline-Schritte wie sh werden auf Agents ausgeführt, aber Groovy-Logik im Jenkinsfile kann auf dem Controller laufen. Vermeiden Sie es, große Dateien in Groovy-Variablen zu lesen, riesige Maps zu erstellen oder große JSON-Verarbeitungen im Pipeline-Skript durchzuführen. Verwenden Sie Shell, Python, jq oder Ihr Build-Tool auf dem Agent für schwere Datenarbeit.

Agents sind überlastet oder nicht passend

Wenn die Warteschlangenzeit für ein Label hoch ist, hilft das Hinzufügen generischer Executoren nicht. Ein Job, der linux && docker && large-memory erfordert, benötigt genau diese Kapazität.

Sehen Sie sich die Warteschlangengründe und die Label-Nutzung an. Überprüfen Sie dann das Agent-Betriebssystem:

uptime
free -h
mpstat 1
iostat -xz 1
docker system df

Wenn ein Agent swapped, reduzieren Sie die Executoren oder erhöhen Sie den Speicher. Wenn die CPU ausgelastet ist und die Build-Dauer während Stoßzeiten steigt, reduzieren Sie die Parallelität oder fügen Sie Agents hinzu. Wenn die I/O-Wartezeit hoch ist, verschieben Sie Caches und Workspaces auf schnelleren Speicher oder verringern Sie die Anzahl der gleichzeitigen Jobs auf diesem Knoten.

Für Kubernetes-Agents sind Ressourcenanfragen genauso wichtig wie die Jenkins-Executor-Anzahl. Ein Pod, der zu wenig CPU oder Speicher anfordert, kann auf einen bereits ausgelasteten Knoten geplant werden, und dann sieht Jenkins einen bereiten Agent, während der Build kriecht. Für wegwerfbare Pods ist ein Executor pro Pod normalerweise einfacher zu handhaben als mehrere Executoren, die denselben Container teilen.

Plugin-Probleme

Plugins sind eine der Stärken von Jenkins und auch eine häufige Quelle für Leistungsprobleme. Ein Plugin kann Seitenrendering-Kosten hinzufügen, das Laden von Jobs verlangsamen, zu viele Build-Verläufe aufbewahren oder während normaler UI-Aktionen externe Aufrufe tätigen.

Wenn sich die Leistung plötzlich ändert, fragen Sie, was sich kürzlich geändert hat:

  • Jenkins-Core-Upgrade.
  • Plugin-Upgrade.
  • Neue Plugin-Installation.
  • Neue globale Konfiguration.
  • Neue Pipeline-Bibliotheksversion.

Verwenden Sie die "Jenkins verwalten"-Gesundheitsinformationen, Protokolle und Plugin-Änderungsprotokolle. Wenn die Benutzeroberfläche nach einem Plugin-Update langsam wurde, testen Sie einen Rollback in einem Staging-Controller, falls vorhanden. Halten Sie ein Backup von JENKINS_HOME und Plugin-Versionen vor großen Upgrades bereit.

Behalten Sie keine Plugins "nur für den Fall". Jedes installierte Plugin erhöht die Wartungsoberfläche. Entfernen Sie ungenutzte Plugins, nachdem Sie die Job-Abhängigkeiten überprüft haben.

SCM- und Artefakt-Repository-Verzögerungen

Viele "Jenkins ist langsam"-Berichte sind eigentlich Probleme mit Git, Paketregistern, Containerregistern oder Artefakt-Repositories.

Überprüfen Sie Build-Protokolle auf wiederholte langsame Schritte:

git fetch
mvn dependency:resolve
npm ci
docker pull
docker push
archiveArtifacts

Wenn jeder Job auf Abhängigkeits-Downloads wartet, fügen Sie einen nahegelegenen Proxy oder Cache hinzu. Wenn git fetch langsam ist, überprüfen Sie die Repository-Größe, Branch-Erkennung, Shallow-Clone-Einstellungen und den Netzwerkpfad von Agents zum Git-Server. Wenn Docker-Pulls auf ephemeren Agents langsam sind, verwenden Sie einen Registry-Mirror oder BuildKit-Registry-Cache.

Bleiben Sie bei der Diagnose ehrlich: Jenkins plant die Arbeit, aber es kann ein entferntes Paketregister nicht schnell machen.

Log- und Build-Verlaufsaufblähung

Große Konsolenprotokolle verlangsamen das Seitenrendering und verbrauchen Speicherplatz. Jobs, die während normaler Builds jedes Test-Fixture, jede HTTP-Antwort oder vollständige Debug-Protokolle ausgeben, machen Jenkins irgendwann unangenehm zu bedienen.

Beheben Sie zuerst den Job. Reduzieren Sie die normale Protokollausführlichkeit und archivieren Sie detaillierte Protokolle nur bei Bedarf als komprimierte Artefakte. Halten Sie die Konsolenausgabe auf Fortschritt und Fehlerkontext fokussiert.

Legen Sie dann die Aufbewahrung fest:

options {
  buildDiscarder(logRotator(daysToKeepStr: '30', numToKeepStr: '50'))
}

Für compliance-intensive Umgebungen verschieben Sie langfristige Artefakte und Protokolle in ein externes Speichersystem, das für Aufbewahrung, Suche und Lebenszyklusrichtlinien ausgelegt ist.

Ein praktischer Vorfallspfad

Wenn Jenkins gerade langsam ist, gehen Sie in dieser Reihenfolge vor:

  1. Überprüfen Sie, ob die Controller-Benutzeroberfläche langsam ist.
  2. Überprüfen Sie Controller-CPU, Speicher, GC-Symptome und Festplatte.
  3. Überprüfen Sie Warteschlangengründe und welche Labels warten.
  4. Überprüfen Sie die am stärksten ausgelasteten Agents auf CPU, Speicher, Festplatte und Workspace-Wachstum.
  5. Vergleichen Sie kürzliche Änderungen an Plugins, Jobs und gemeinsam genutzten Bibliotheken.
  6. Lesen Sie ein langsames Build-Protokoll und identifizieren Sie den wiederholten teuren Schritt.

Dieser Pfad verhindert zufälliges Tuning. Eine Erhöhung des Heaps wird einen gesättigten Docker-Agent nicht beheben. Das Hinzufügen von Executoren wird eine volle Festplatte nicht beheben. Das Bereinigen von Workspaces wird ein Plugin, das Controller-Pausen verursacht, nicht beheben.

Halten Sie Jenkins wartbar

Gesunde Jenkins-Installationen haben langweilige Gewohnheiten: Controller-Executoren auf null gesetzt, Agents für ihre Arbeitslast dimensioniert, Build-Aufbewahrung konfiguriert, Abhängigkeits-Caches absichtlich, Plugin-Updates verfolgt und grundlegende Metriken nach Prometheus, Grafana, CloudWatch oder welches Überwachungssystem das Team auch immer verwendet, exportiert.

Die beste Lösung ist oft klein und spezifisch. Verschieben Sie Docker-Builds auf dedizierte Agents. Reduzieren Sie die Protokollausgabe eines lauten Jobs. Fügen Sie einen Maven-Proxy hinzu. Reduzieren Sie Executoren auf einem swapenden Knoten. Entfernen Sie ein ungenutztes Plugin. Legen Sie eine Aufbewahrung für einen Job fest, der jahrelang jeden Build behalten hat.

Jenkins-Leistung verbessert sich, wenn Sie aufhören, es als eine Blackbox zu behandeln, und beginnen, der Arbeit zu folgen: von der Warteschlange zum Controller zum Agent zum Dateisystem zur Netzwerkabhängigkeit und zurück zum Build-Protokoll.

Beispiel: Der Build ist langsam, aber Jenkins ist in Ordnung

Angenommen, Entwickler berichten, dass Pull-Request-Checks 25 Minuten dauern. Die Jenkins-Benutzeroberfläche ist reaktionsschnell. Die Warteschlange ist kurz. Agents sind online. Das langsame Protokoll zeigt:

git fetch: 20 Sekunden
npm ci: 9 Minuten
Unit-Tests: 4 Minuten
docker build: 10 Minuten
Artefakte archivieren: 1 Minute

Dies ist in erster Linie kein Jenkins-Controller-Problem. Die wahrscheinlichen Lösungen sind Paket-Caching, Dockerfile-Layer-Reihenfolge, BuildKit-Cache und möglicherweise das Aufteilen von Tests. Eine Erhöhung des Controller-Heaps würde nichts ändern.

Beispiel: Alles wartet, aber Agents sind untätig

Wenn Jobs in der Warteschlange sind, während Agents untätig erscheinen, lesen Sie den Warteschlangengrund. Sie könnten feststellen, dass Jobs linux && docker erfordern, während die untätigen Agents nur linux haben. Oder die Jobs könnten durch disableConcurrentBuilds, eine sperrbare Ressource oder ein Cloud-Plugin blockiert sein, das keine passenden Agents bereitstellen kann.

Diese Art von Engpass ist Konfiguration, nicht rohe Kapazität. Das Hinzufügen von zwei weiteren nicht passenden Agents wird nicht helfen.

Beispiel: Der Controller wird jeden Nachmittag langsamer

Wenn die Benutzeroberfläche jeden Tag zur gleichen Zeit nachlässt, suchen Sie nach geplanten Jobs: Branch-Indexierung, Backups, große Artefakt-Bereinigung, Schwachstellen-Scans oder nächtliche Pipelines, die zu früh starten. Überprüfen Sie Controller-CPU, Heap und Festplatten-I/O während dieses Fensters. Überprüfen Sie auch, ob viele Jobs genau zur gleichen Minute aufgrund von Cron-Ausdrücken wie 0 2 * * * starten.

Bevorzugen Sie in Jenkins-Zeitplänen nach Möglichkeit gehashte Zeitsteuerung:

H 2 * * *

Das verteilt Jobs, anstatt alles zur vollen Stunde zu starten.

Was gute Überwachung beantworten sollte

Mindestens sollte die Überwachung diese Fragen beantworten, ohne sich auf dem Server anzumelden:

  • Ist der Controller-Prozess lebendig und reaktionsschnell?
  • Wie viel Heap wird verwendet und wie oft läuft die Garbage Collection?
  • Wie lange warten Jobs in der Warteschlange nach Label?
  • Welche Agents sind offline oder verbinden sich wiederholt neu?
  • Sind Controller- und Agent-Festplatten fast voll?
  • Werden Builds für dieselben Jobs im Laufe der Zeit langsamer?

Sie brauchen kein perfektes Dashboard, um zu beginnen. Selbst ein paar Metriken und Warnungen für Festplatte, Heap, Warteschlangenlänge und Agent-Verfügbarkeit werden viele Ausfälle abfangen, bevor Entwickler sie melden.