Analyse eines Produktionsausfalls durch Weblogic Compiler Threads
7.2.2012 | 3 Minuten Lesezeit
Kürzlich besuchte ich einen Kunden um dessen Anwendungsmonitoring mit AppDynamics weiter zu verbessern. Bei meiner Ankunft wurde ich mit folgenden Worten begrüßt:
„Super, dass Du da bist, Fabian. Wir können Dir ganz interessante Dinge aus dem Monitoring zeigen“. Normalerweise sind Leute aus dem Betrieb sehr besorgt, wenn sie mir so etwas sagen. Doch in diesem Fall waren sie sehr entspannt, fast schon fröhlich. „Wir hatten einen großen Produktionsausfall am Samstag als wir die neue Software live genommen haben. Nichts ging mehr!“ Oh jeh!? Was war passiert? Und warum sind die trotz des Ausfalls so gut gelaunt? Niemand mag Produktionsausfälle am Wochenende. „Ja, das war schon ein langer Samstag, aber immerhin haben wir ein Monitoring was uns gesagt hat was los war“.
Nun, schauen wir uns mal an was an diesem Samstag so passiert ist, und was das Problem war, welches den Ausfall verursacht hat.
Ein Überblick über die Situation
Hier ein Bild von dem was an dem Samstag um 8 Uhr morgens vorgefallen ist.
Für alle diejenigen die AppDynamics nicht kennen, hier eine kurze Einweisung in die Oberfläche:
- Der größte Bereich ist die sogenannte „Application Flow Map“. AppDynamics erkennt alle Server automatisch und überwacht ihre Kommunikation miteinander.
- Auf der rechten Seite gibt es einige Statistiken. Wir sehen „Stalls“ und „Abnormal Slow requests“. AppDynamics hat also auch bemerkt, dass etwas nicht so ist wie es sein sollte.
- Unten sehen wir die historische Ansicht. Da es sich zum Zeitpunkt meiner Analyse um historische Daten älter als 2 Tage handelt, wurden sie schon auf Stundenlevel aggregiert. Zum Zeitpunkt des Ausfalls selbst lagen die Daten minütlich vor.
Da wir zurückblicken sind die historischen Daten für uns am interessantesten.
Wir sehen auf der linken Seite den Serverstart (blaue Icons auf grünem Balken). Die Last auf das System stieg schnell an (grüne Balken). Doch das System brach dann schnell zusammen. Die Antwortzeiten (blaue Linie) stiegen und die Anzahl der Requests ging auf 0 zurück. Die Server waren abgestürzt und mussten neu gestartet werden.
Aber der Restart alleine half nicht. Erst die Korrektur des Problems später normalisierte die Lage 🙂
Was genau war passiert?
Die Server stürzten mit einem OutOfMemory Error ab. In unserer OutOfMemoryError Serie , haben wir bereits einige Probleme diskutiert, doch hier ist ein Neues: „Unable to create native thread“.
Dieser Fehler ist in der Tat sehr interessant. Ausfälle mit einem solchen Fehler deuten eher auf Konfigurationsprobleme oder einem Fehler beim Threadmanagement hin, nicht auf inperformanten Code. Also schaute ich mir die Anzahl der Threads an, welche AppDynamics mitgemessen hat:
Ouch. Das System hatte bereits 1800 Threads erzeugt als es abstürzte.
Was erzeugt also diese Threads? Ich kannte das bereits von anderen Kunden, und auch dieser Kunde konnte anhand von einigen Stall-Snapshots schnell sehen was passiert war. Die JSP Kompilation war schuldig.
Alle Applikationsserver haben die Option JSPs bereits beim Serverstart, oder erst wenn durch den Benutzer angefordert, zu kompilieren. Beide Optionen sind aber problematisch wenn der Server bereits unter hoher Last gestartet wird.
Behoben wurde das Problem am Sonntag Morgen um 4. Jedoch musste das Betriebsteam nicht so lange aufbleiben, das sie bereits gegen Mittag einen qualifizierten Fehlerbericht an Oracle gesendet hatten. Die „Korrektur“ von Oracle erfolgte etwas später. Die notwendige Option selbst ist nirgendwo dokumentiert, zumindest nicht so, dass man sie finden kann ohne sie zu kennen.
Hier ein Screenshot aus AppDynamics, der diese Konfigurationsänderung dokumentiert.
JSP Compiler Threads auf Weblogic begrenzen
Der geheime Schalter war eine Umgebungsvariable die gesetzt werden muss:
BEA_COMPILER_NUM_THREADS = 1
Natürlich ist 1 sehr pessimistisch. Jedoch scheint dies die weit bessere Option zu sein als „unbegrenzt“, was die Standardeinstellung zu sein scheint. Niemand sollte jemals unbegrenzt Threads erzeugen. Klassisch gesehen sollte man nur so viele Threads haben wie sich auch Prozessoren in dem Server befinden. Moderne JVMs können jedoch auch gut 10 mal so viele Threads verwalten, solange sie nicht alle die CPU benötigen. Doch hier hatten wir fast 100 Compiler Threads pro CPU.
Weitere Beiträge
von Fabian Lange
Dein Job bei codecentric?
Jobs
Agile Developer und Consultant (w/d/m)
Alle Standorte
Gemeinsam bessere Projekte umsetzen.
Wir helfen deinem Unternehmen.
Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.
Hilf uns, noch besser zu werden.
Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.
Blog-Autor*in
Fabian Lange
Du hast noch Fragen zu diesem Thema? Dann sprich mich einfach an.
Du hast noch Fragen zu diesem Thema? Dann sprich mich einfach an.