SchwarzerEngel Geschrieben 17. Februar 2011 Teilen Geschrieben 17. Februar 2011 Guten Morgen! Ich habe hier folgendes Szenario: auf einem Linuxserver läuft ein Java-Server-Prozess, welcher – unter anderem – eine Jar-Datei („server.jar“) im Klassenpfad enthält, welche global verwendete Klassen zur Verfügung stellt. Wenn sich nun innerhalb dieser Jar-Datei eine Klasse ändert oder Neue hinzu kommen, dann muss ich den Server-Prozess neu starten, um die aktualisierten Klassen zu ziehen. Soweit richtig? Das Problem ist, dass durch den Neustart alle bestehenden Verbindungen zu den Clients getrennt werden. Das ist bei einer produktiven Anwendung natürlich ein No-Go. Natürlich könnte ich den Neustart nachts zeitgesteuert automatisch durchführen, wenn keine User angemeldet sind. Unser Auftraggeber wünscht jedoch, dass manche Änderungen einfach "ad-hoc" zur Verfügung stehen. Nun also die Frage: Gibt es eine Möglichkeit, den Klassenpfad für den Server-Prozess zur Laufzeit zu aktualisieren ohne dass dieser beendet werden muss? Irgendwie einen Refresh oder eine andere simple Möglichkeit der Anwendung zu sagen, dass sie den Classpath neu einlesen soll? Danke im Voraus. Greetz S.E. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
flashpixx Geschrieben 17. Februar 2011 Teilen Geschrieben 17. Februar 2011 Nein das geht nicht, der Classpath ist während der Ausführung statisch. Denn wenn es möglich wäre, dann könnte man Klassen & Packages während der Laufzeit entfernen und damit könnte evtl manche Objekte nicht mehr erzeugt werden. Was evtl ginge. Die Jar Datei auflösen und die Klassen einzeln speichern. Dann diese Pfade dem Classpath hinzufügen. Wenn nun eine Klasse ersetzt werden muss, muss zuerst sichergestellt werden, dass kein Objekt von dieser Klasse instatiiert ist, dann muss die Datei ersetzt werden, danach sollte dann bei einer Neuinstantiierung die neue Klasse geladen werden. Ich halte dieses aber für absolut fahrlässig zur Laufzeit Systemkomponenten auszutauschen. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
SchwarzerEngel Geschrieben 17. Februar 2011 Autor Teilen Geschrieben 17. Februar 2011 Danke für deine schnelle Antwort, flashpixx! Ich halte dieses aber für absolut fahrlässig zur Laufzeit Systemkomponenten auszutauschen. Danke für diesen Satz - ich sehe das im Prinzip genau so und habe das unserem Auftraggeber auch schon "durch die Blume" so gesagt! Leider hat der Kollege vom Fachbereich eher die Einstellung a la "da muss es doch eine Möglichkeit geben". Mein Vorschlag mit den automatisierten nächtlichen Restarts war ihm nicht genug - als ob ein Prod-Restart im laufenden Betrieb besser wäre.... Ich wollte halt einfach mal hier nachfragen, da ich von mir auch nicht behaupten kann, dass ich alles weiß! Nochmals Danke! Gruß S.E. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
flashpixx Geschrieben 17. Februar 2011 Teilen Geschrieben 17. Februar 2011 (bearbeitet) Mach einen Restart nachts, das sind einige Sekunden, ich denke das ist zu verkraften. Bei einer on-fly Ersetzung wirst Du das Problem bekommen, dass Du zwar alle Objekte zerstört hast, der Garbage Collector aber die Verweise aus dem Speicher noch nicht entfernt hat, somit kannst Du auf Dateiebene die Klasse nicht ersetzen, weil sie ja noch im Zugriff ist. D.h. Du müsstest vor der Ersetzung manuell immer den GC laufen lassen, alleine so ein Lauf ist sehr unperformant und dauert, da ist ein manueller Restart einfach schneller und effizienter Ich weiß auch nicht 100%ig ob es überhaupt möglich ist eine Klassendatei, nachdem sie einmal instantiiert wurde, auf Dateiebene zu ersetzen, wenn sie nicht mehr im Zugriff ist. Es könnte sein, dass die VM trotzdem einen Filelock fürs Caching aufrecht erhält um bei einer Neuinstantiierung schneller die Klasse zu finden und zu laden. Also bevor Du da irgendein Frickelwerk baust, mach es Standardkonform bei Unixen kann man das über einen init.d Prozess und Cron regeln und bei Windows geht das über den Taskplaner + ein Commandozeilenscript ebenfalls automatisiert Bearbeitet 17. Februar 2011 von flashpixx Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
kingofbrain Geschrieben 22. Februar 2011 Teilen Geschrieben 22. Februar 2011 Also prinzipiell geht das schon, Du musst allerdings einen eigenen Classloader definieren (evtl. sogar einen eigenen implementieren). Wenn Du schauen willst, wie sowas funktioniert, dann kannst Du Dir mal das Thema Classloading im JBoss Application Server anschauen, die machen das beim Hot Deploy ja auch. Was Du allerdings berücksichtigen musst, ist folgendes: alle bereits geladenen Klassen werden, wenn sie nicht mehr benötigt werden, in der Permanent Generation des Garbage Collectors abgelegt. Das heißt, diese werden niemals gelöscht. Deswegen wird bei einem Hot Deploy irgendwann dieser Bereich des Speichers volllaufen. Fazit: geht prinzipiell, sollte man aber in meinen Augen in einer produktiven Umgebung nicht machen. Dann lieber das System in einer geclusterten Umgebung starten mit der Möglichkeit, zeitgesteuert keine neuen User Sessions auf einem Knoten anzulegen, und bei Ablauf der letzten Session den Server neu starten. Das selbe auf allen anderen Knoten auch und gut ist. Und es gibt keine spürbare Downtime. Schöne Grüße, Peter Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.