Spring Boot-Anwendung herunterfahren

Fahren Sie eine Spring Boot-Anwendung herunter

1. Überblick

Die Verwaltung des Lebenszyklus von Spring Boot Application ist für ein produktionsreifes System sehr wichtig. Der Spring-Container übernimmt die Erstellung, Initialisierung und Zerstörung aller Bohnen mithilfe derApplicationContext.

Der Schwerpunkt dieses Aufsatzes liegt auf der Zerstörungsphase des Lebenszyklus. Im Einzelnen werden verschiedene Möglichkeiten zum Herunterfahren einer Spring Boot-Anwendung vorgestellt.

Weitere Informationen zum Einrichten eines Projekts mit Spring Boot finden Sie im ArtikelSpring Boot Starteroder inSpring Boot Configuration.

2. Endpunkt herunterfahren

Standardmäßig sind alle Endpunkte in Spring Boot Application außer/shutdown aktiviert. Dies ist natürlich Teil der Endpunkte vonActuator.

Hier ist die Maven-Abhängigkeit, um diese einzurichten:


    org.springframework.boot
    spring-boot-starter-actuator

Und wenn wir auch Sicherheitsunterstützung einrichten möchten, benötigen wir:


    org.springframework.boot
    spring-boot-starter-security

Zuletzt aktivieren wir den Endpunkt zum Herunterfahren in der Dateiapplication.properties:

management.endpoints.web.exposure.include=*
management.endpoint.shutdown.enabled=true
endpoints.shutdown.enabled=true

Beachten Sie, dass wir auch alle Aktuatorendpunkte verfügbar machen müssen, die wir verwenden möchten. Im obigen Beispiel haben wir alle Aktuatorendpunkte verfügbar gemacht, die den Endpunkt von/shutdownenthalten.

To shut down the Spring Boot application, we simply call a POST method like this:

curl -X POST localhost:port/actuator/shutdown

In diesem Aufruf repräsentiertport den Aktuatorport.

3. Anwendungskontext schließen

Wir können dieclose()-Methode auch direkt über den Anwendungskontext aufrufen.

Beginnen wir mit einem Beispiel zum Erstellen und Schließen eines Kontexts:

ConfigurableApplicationContext ctx = new
  SpringApplicationBuilder(Application.class).web(WebApplicationType.NONE).run();
System.out.println("Spring Boot application started");
ctx.getBean(TerminateBean.class);
ctx.close();

This destroys all the beans, releases the locks, then closes the bean factory. Um das Herunterfahren der Anwendung zu überprüfen, verwenden wir den Standard-Lebenszyklus-Rückruf von Spring mit der Anmerkung@PreDestroy:

public class TerminateBean {

    @PreDestroy
    public void onDestroy() throws Exception {
        System.out.println("Spring Container is destroyed!");
    }
}

Wir müssen auch eine Bohne dieses Typs hinzufügen:

@Configuration
public class ShutdownConfig {

    @Bean
    public TerminateBean getTerminateBean() {
        return new TerminateBean();
    }
}

Hier ist die Ausgabe nach dem Ausführen dieses Beispiels:

Spring Boot application started
Closing [email protected]
DefaultLifecycleProcessor - Stopping beans in phase 0
Unregistering JMX-exposed beans on shutdown
Spring Container is destroyed!

Das Wichtigste dabei ist:while closing the application context, the parent context isn’t affected due to separate lifecycles.

3.1. Schließen Sie den aktuellen Anwendungskontext

Im obigen Beispiel haben wir einen untergeordneten Anwendungskontext erstellt und ihn dann mit der Methodeclose()zerstört.

Wenn wir den aktuellen Kontext schließen möchten, besteht eine Lösung darin, einfach den Endpunkt des Aktuators/shutdownaufzurufen.

Wir können jedoch auch einen eigenen benutzerdefinierten Endpunkt erstellen:

@RestController
public class ShutdownController implements ApplicationContextAware {

    private ApplicationContext context;

    @PostMapping("/shutdownContext")
    public void shutdownContext() {
        ((ConfigurableApplicationContext) context).close();
    }

    @Override
    public void setApplicationContext(ApplicationContext ctx) throws BeansException {
        this.context = ctx;

    }
}

Hier haben wir einen Controller hinzugefügt, der dieApplicationContextAware-Schnittstelle implementiert und die Setter-Methode überschreibt, um den aktuellen Anwendungskontext zu erhalten. In einer Zuordnungsmethode rufen wir dann einfach die Methodeclose()auf.

Wir können dann unseren neuen Endpunkt aufrufen, um den aktuellen Kontext zu beenden:

curl -X POST localhost:port/shutdownContext

Wenn Sie einen Endpunkt wie diesen in einer realen Anwendung hinzufügen, möchten Sie ihn natürlich auch sichern.

4. Beenden SieSpringApplication

SpringApplication registriert einenshutdown-Hook bei der JVM, um sicherzustellen, dass die Anwendung ordnungsgemäß beendet wird.

Beans können dieExitCodeGenerator-Schnittstelle implementieren, um einen bestimmten Fehlercode zurückzugeben:

ConfigurableApplicationContext ctx = new SpringApplicationBuilder(Application.class)
  .web(WebApplicationType.NONE).run();

int exitCode = SpringApplication.exit(ctx, new ExitCodeGenerator() {
@Override
public int getExitCode() {
        // return the error code
        return 0;
    }
});

System.exit(exitCode);

Der gleiche Code mit der Anwendung von Java 8 Lambdas:

SpringApplication.exit(ctx, () -> 0);

After calling the System.exit(exitCode), the program terminates with a 0 return code:

Process finished with exit code 0

5. Beenden Sie den App-Prozess

Schließlich können wir eine Spring Boot-Anwendung auch von außerhalb der Anwendung mithilfe eines Bash-Skripts beenden. Unser erster Schritt für diese Option besteht darin, dass der Anwendungskontext die PID in eine Datei schreibt:

SpringApplicationBuilder app = new SpringApplicationBuilder(Application.class)
  .web(WebApplicationType.NONE);
app.build().addListeners(new ApplicationPidFileWriter("./bin/shutdown.pid"));
app.run();

Erstellen Sie als Nächstes eineshutdown.bat-Datei mit folgendem Inhalt:

kill $(cat ./bin/shutdown.pid)

Die Ausführung vonshutdown.bat extrahiert die Prozess-ID aus der Dateishutdown.pid und beendet die Boot-Anwendung mit dem Befehlkill.

6. Fazit

In diesem kurzen Artikel haben wir einige einfache Methoden behandelt, mit denen eine laufende Spring Boot-Anwendung heruntergefahren werden kann.

Während es Sache des Entwicklers ist, eine geeignete Methode auszuwählen; Alle diese Methoden sollten beabsichtigt und absichtlich angewendet werden.

Zum Beispiel wird.exit() bevorzugt, wenn wir einen Fehlercode an eine andere Umgebung übergeben müssen, z. B. JVM für weitere Aktionen. Verwenden vonApplication PID gives more flexibility, as we can also start or restart the application unter Verwendung eines Bash-Skripts.

Schließlich ist/shutdown hier, umterminate the applications externally via HTTP zu ermöglichen. In allen anderen Fällen funktionieren.close() einwandfrei.

Wie üblich ist der vollständige Code für diesen Artikel überGitHub project verfügbar.