Was ist der beste Weg, um neuen Code auf einen Produktionsringserver zu übertragen, ohne die gesamte JVM neu zu starten?
Momentan verwende ich Wrap-Reload in der Produktion, aber das funktioniert nicht ganz für mich, weil ich manchmal Befehle im repl ausführen möchte (zum Beispiel Datenbankmigrationen), bevor der Ring beginnt, Anfragen mit dem neuen Code zu bearbeiten. Auch verschiedene Blogs und Tutorials sagen, dass sie kein Wrap-Reload in der Produktion verwenden sollten, obwohl ich nicht verstehe, warum nicht.
Ich habe die folgende Lösung gefunden, aber ich gestehe, dass ich kein tiefes Verständnis davon habe, was unter der Haube passiert. Ich habe mich gefragt, ob ich von jemandem, der das tut, eine Plausibilitätsprüfung bekommen könnte. Scheint diese Technik sinnvoll?
Die Idee ist, einen Pfad (/ admin / reload-clj) zu haben, der bewirkt, dass der gesamte clojure-Code neu geladen wird.
%Vor% Der Code, den Sie haben, wird funktionieren, obwohl Sie wissen sollten, dass :reload-all
nur einen Namespace und die Namespaces-Abhängigkeiten lädt. Es lädt nicht rekursiv Abhängigkeiten von diese Namespaces.
Ich sollte hinzufügen, dass das Nachladen auf diese Weise in einem Produktionssystem nicht unbedingt empfohlen wird.
Neu implementierter Code weist möglicherweise Fehler auf, die erst beim Neustart des Systems erkannt werden (z. B. hängen sie von einer Variablen ab, die noch vom ausgeführten System definiert wird, deren Deklaration jedoch entfernt wurde). Das System funktioniert gut, scheitert aber beim Neustart.
Das Laden von Code kann auch Nebenwirkungen haben, die Ihre Produktionsumgebung beschädigen könnten. Obwohl es ein guter Stil ist, diese zu vermeiden, besteht die einzige Möglichkeit, wirklich sicher zu sein, dass etwas Unerwartetes nicht passieren wird, darin, einen JVM-Neustart durchzuführen.
Der beste Weg für eine Bereitstellung ohne Ausfallzeit auf der JVM ist eine rollende Bereitstellung mithilfe eines Lastenausgleichsmoduls.
Ich hatte einen Intranet-Webdienst in Lisp bei einem früheren Job, also weiß ich nicht, ob dies als Produktion qualifiziert. Auch in CL ist meine Antwort weder ring- noch clojurespezifisch. Dennoch ist es nützlich, Code neu zu laden.
Ich habe einen Swank-Server (Teil des Slime) in der Production-Lisp-Instanz gestartet und eine Verbindung dazu auch von meinem Desktop aus hergestellt. Auf diese Weise könnte ich neuen Code schreiben, Code umschreiben, debuggen, neu laden usw. Natürlich müssen Sie in einem realen Produktionssystem besonders vorsichtig sein.
Sie können in clojure ähnlich verfahren, Sie haben sogar Alternativen zum swank, wie nrepl.
Sie müssen auch die Sicherheit berücksichtigen und nur lokale Verbindungen zulassen oder was auch immer für Sie funktioniert.