Menutup Aplikasi Spring Boot

1. Gambaran keseluruhan

Menguruskan kitaran hidup Spring Boot Application sangat penting untuk sistem siap pengeluaran. Kontena Spring menangani penciptaan, inisialisasi, dan pemusnahan semua Beans dengan bantuan ApplicationContext.

Penekanan penulisan ini adalah fasa pemusnahan kitaran hidup. Lebih khusus lagi, kita akan melihat pelbagai cara untuk menutup Aplikasi Spring Boot.

Untuk mengetahui lebih lanjut mengenai cara menyiapkan projek menggunakan Spring Boot, lihat artikel Spring Boot Starter, atau baca Spring Boot Configuration.

2. Titik Akhir Penutupan

Secara lalai, semua titik akhir diaktifkan dalam Spring Boot Application kecuali / shutdown ; ini, secara semula jadi, adalah sebahagian daripada titik akhir Penggerak .

Inilah kebergantungan Maven untuk mengaturnya:

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

Dan, jika kami juga ingin menyediakan sokongan keselamatan, kami memerlukan:

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

Terakhir, kami mengaktifkan titik akhir penutupan dalam fail application.properties :

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

Perhatikan bahawa kita juga harus mendedahkan titik akhir penggerak yang ingin kita gunakan. Dalam contoh di atas, kami telah mendedahkan semua titik akhir penggerak yang akan merangkumi titik akhir / penutupan .

Untuk mematikan aplikasi Spring Boot, kami hanya memanggil kaedah POST seperti ini :

curl -X POST localhost:port/actuator/shutdown

Dalam panggilan ini, port mewakili port penggerak.

3. Tutup Konteks Aplikasi

Kita juga boleh memanggil kaedah tutup () secara langsung menggunakan konteks aplikasi.

Mari kita mulakan dengan contoh membuat konteks dan menutupnya:

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

Ini menghancurkan semua biji, melepaskan kunci, kemudian menutup kilang kacang . Untuk mengesahkan penutupan aplikasi, kami menggunakan panggilan balik kitaran hidup standard Spring dengan anotasi @PreDestroy :

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

Kita juga harus menambah kacang jenis ini:

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

Inilah hasilnya setelah menjalankan contoh ini:

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

Perkara penting yang perlu diingat: semasa menutup konteks aplikasi, konteks ibu bapa tidak terjejas kerana kitaran hayat yang berasingan .

3.1. Tutup Konteks Aplikasi Semasa

Dalam contoh di atas, kami membuat konteks aplikasi anak, kemudian menggunakan kaedah close () untuk menghancurkannya.

Sekiranya kita ingin menutup konteks semasa, satu penyelesaian adalah dengan memanggil titik akhir penggerak / penutupan .

Walau bagaimanapun, kami juga dapat membuat titik akhir tersuai kami sendiri:

@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; } }

Di sini, kami telah menambahkan pengawal yang menerapkan antara muka ApplicationContextAware dan mengesampingkan kaedah setter untuk memperoleh konteks aplikasi semasa. Kemudian, dalam kaedah pemetaan, kita hanya memanggil kaedah tutup () .

Kami kemudian boleh memanggil titik akhir baru kami untuk mematikan konteks semasa:

curl -X POST localhost:port/shutdownContext

Sudah tentu, jika anda menambahkan titik akhir seperti ini dalam aplikasi kehidupan nyata, anda juga mahu mendapatkannya.

4. Keluar Permohonan Spring

SpringApplication mendaftarkan cangkuk penutupan dengan JVM untuk memastikan aplikasi keluar dengan betul.

Kacang boleh melaksanakan antara muka ExitCodeGenerator untuk mengembalikan kod ralat tertentu:

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);

Kod yang sama dengan penerapan Java 8 lambdas:

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

Setelah memanggil System.exit (exitCode) , program ini berakhir dengan kod pengembalian 0 :

Process finished with exit code 0

5. Bunuh Proses Aplikasi

Akhirnya, kita juga dapat mematikan Aplikasi Spring Boot dari luar aplikasi dengan menggunakan skrip bash. Langkah pertama kami untuk pilihan ini adalah membuat konteks aplikasi menulis PID ke dalam fail:

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

Seterusnya, buat fail shutdown.bat dengan kandungan berikut:

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

Pelaksanaan shutdown.bat mengekstrak ID Proses dari fail shutdown.pid dan menggunakan perintah kill untuk menghentikan aplikasi Boot.

6. Kesimpulannya

Dalam penulisan ringkas ini, kami telah membahas beberapa kaedah mudah yang dapat digunakan untuk mematikan Aplikasi Spring Boot yang sedang berjalan.

Walaupun terpulang kepada pemaju untuk memilih kaedah yang sesuai; semua kaedah ini harus digunakan dengan reka bentuk dan sengaja.

Sebagai contoh, .exit () lebih disukai apabila kita perlu menghantar kod ralat ke persekitaran lain, katakan JVM untuk tindakan selanjutnya. Menggunakan PID Aplikasi memberikan lebih banyak fleksibiliti, kerana kita juga dapat memulai atau menghidupkan kembali aplikasi dengan penggunaan skrip bash.

Akhirnya, / shutdown ada di sini untuk memungkinkan untuk menghentikan aplikasi secara luaran melalui HTTP . Untuk semua kes lain. Tutup () akan berfungsi dengan sempurna.

Seperti biasa, kod lengkap untuk artikel ini terdapat di projek GitHub.