Dalam Dokumen Spring Boot, mereka mengatakan bahwa 'Setiap SpringApplication akan mendaftarkan hook shutdown dengan JVM untuk memastikan bahwa ApplicationContext ditutup dengan anggun saat keluar.'
Ketika saya mengklik ctrl+c
perintah shell, aplikasi dapat dimatikan dengan baik. Jika saya menjalankan aplikasi di mesin produksi, saya harus menggunakan perintah
java -jar ProApplicaton.jar
. Tetapi saya tidak dapat menutup terminal shell, jika tidak maka proses akan ditutup.
Jika saya menjalankan perintah seperti nohup java -jar ProApplicaton.jar &
, saya tidak dapat menggunakan ctrl+c
untuk mematikannya dengan baik.
Apa cara yang benar untuk memulai dan menghentikan Aplikasi Spring Boot di lingkungan produksi?
linux
spring
spring-boot
Chris
sumber
sumber
kill -SIGTERM <PID>
seharusnya berhasil.Jawaban:
Jika Anda menggunakan modul aktuator, Anda dapat mematikan aplikasi melalui
JMX
atauHTTP
jika titik akhir diaktifkan.tambahkan ke
application.properties
:URL berikut akan tersedia:
/actuator/shutdown
- Mengizinkan aplikasi untuk dimatikan dengan baik (tidak diaktifkan secara default).Bergantung pada bagaimana titik akhir diekspos, parameter sensitif dapat digunakan sebagai petunjuk keamanan.
Misalnya, titik akhir sensitif akan memerlukan nama pengguna / kata sandi saat diakses
HTTP
(atau dinonaktifkan jika keamanan web tidak diaktifkan).Dari dokumentasi boot Spring
sumber
Berikut adalah opsi lain yang tidak mengharuskan Anda mengubah kode atau mengekspos titik akhir penonaktifan. Buat skrip berikut dan gunakan untuk memulai dan menghentikan aplikasi Anda.
start.sh
Memulai aplikasi Anda dan menyimpan id proses dalam sebuah file
stop.sh
Menghentikan aplikasi Anda menggunakan id proses yang disimpan
start_silent.sh
Jika Anda perlu memulai aplikasi menggunakan ssh dari mesin jarak jauh atau pipeline CI, gunakan skrip ini untuk memulai aplikasi Anda. Menggunakan start.sh secara langsung dapat membuat shell hang.
Setelah mis. menerapkan kembali / menerapkan aplikasi Anda, Anda dapat memulainya kembali menggunakan:
sumber
nohup
maka Anda bisa menggabungkan perintahMengenai jawaban @Jean-Philippe Bond,
berikut adalah contoh cepat maven bagi pengguna maven untuk mengonfigurasi titik akhir HTTP untuk mematikan aplikasi web boot musim semi menggunakan aktuator spring-boot-starter sehingga Anda dapat menyalin dan menempel:
1.Maven pom.xml:
2.aplikasi.properties:
Semua titik akhir tercantum di sini :
3. Kirim metode posting untuk mematikan aplikasi:
Catatan Keamanan:
jika Anda membutuhkan metode shutdown yang dilindungi oleh auth, Anda mungkin juga perlu
konfigurasikan detail :
sumber
server.contextPath=/appName
dalam application.properties saya Jadi sekarang perintah untuk mematikan akan menjadi:curl -X POST localhost:8080/appName/shutdown
Semoga ini dapat membantu seseorang. Saya harus berjuang keras karena kesalahan ini.endpoints.shutdown.enabled=true management.security.enabled=false
.Anda dapat membuat aplikasi springboot untuk menulis PID ke dalam file dan Anda dapat menggunakan file pid untuk menghentikan atau memulai ulang atau mendapatkan status menggunakan skrip bash. Untuk menulis PID ke file, daftarkan listener ke SpringApplication menggunakan ApplicationPidFileWriter seperti yang ditunjukkan di bawah ini:
Kemudian tulis skrip bash untuk menjalankan aplikasi spring boot. Referensi .
Sekarang Anda dapat menggunakan skrip untuk memulai, menghentikan, atau memulai ulang.
sumber
Semua jawaban tampaknya kehilangan fakta bahwa Anda mungkin perlu menyelesaikan beberapa bagian pekerjaan secara terkoordinasi selama penghentian yang dilakukan dengan baik (misalnya, dalam aplikasi perusahaan).
@PreDestroy
memungkinkan Anda untuk mengeksekusi kode shutdown dalam kacang individu. Sesuatu yang lebih canggih akan terlihat seperti ini:sumber
Saya tidak mengekspos titik akhir apa pun dan mulai ( dengan nohup di latar belakang dan tanpa file yang dibuat melalui nohup ) dan berhenti dengan skrip shell (dengan KILL PID dengan anggun dan paksa bunuh jika aplikasi masih berjalan setelah 3 menit ). Saya baru saja membuat jar yang dapat dieksekusi dan menggunakan penulis file PID untuk menulis file PID dan menyimpan Jar dan Pid dalam folder dengan nama yang sama dengan nama aplikasi dan skrip shell juga memiliki nama yang sama dengan start dan stop pada akhirnya. Saya menyebutnya skrip stop dan memulai skrip melalui pipeline jenkins juga. Tidak ada masalah sejauh ini. Bekerja sempurna untuk 8 aplikasi (Skrip yang sangat umum dan mudah diterapkan untuk aplikasi apa pun).
Kelas Utama
FILE YML
Berikut ini skrip awal (start-appname.sh):
Berikut ini skrip stop (stop-appname.sh):
sumber
Spring Boot menyediakan beberapa aplikasi pendengar saat mencoba membuat konteks aplikasi salah satunya adalah ApplicationFailedEvent. Kita bisa gunakan untuk mengetahui apakah konteks aplikasi diinisialisasi atau tidak.
Tambahkan ke kelas pendengar di atas ke SpringApplication.
sumber
Mulai Spring Boot 2.3 dan yang lebih baru, ada mekanisme pematian anggun bawaan .
Pre-Spring Boot 2.3 , tidak ada mekanisme shutdown anggun yang out-of-the-box. Beberapa permulaan boot musim semi menyediakan fungsionalitas ini:
Saya penulis nr. 1. Starter diberi nama "Hiatus for Spring Boot". Ia bekerja pada tingkat penyeimbang beban, yaitu cukup menandai layanan sebagai OUT_OF_SERVICE, tidak mengganggu konteks aplikasi dengan cara apa pun. Hal ini memungkinkan untuk melakukan penonaktifan yang anggun dan berarti, jika diperlukan, layanan dapat dihentikan layanannya untuk beberapa waktu dan kemudian dihidupkan kembali. Kelemahannya adalah itu tidak menghentikan JVM, Anda harus melakukannya dengan
kill
perintah. Karena saya menjalankan semuanya dalam wadah, ini bukan masalah besar bagi saya, karena saya harus berhenti dan melepaskan wadah itu juga.Nomor 2 dan 3 kurang lebih didasarkan pada posting ini oleh Andy Wilkinson. Mereka bekerja satu arah - sekali dipicu, mereka akhirnya menutup konteksnya.
sumber
SpringApplication secara implisit mendaftarkan hook shutdown dengan JVM untuk memastikan bahwa ApplicationContext ditutup dengan baik saat keluar. Itu juga akan memanggil semua metode kacang yang diberi anotasi
@PreDestroy
. Itu berarti kita tidak harus secara eksplisit menggunakanregisterShutdownHook()
metode aConfigurableApplicationContext
dalam aplikasi boot, seperti yang harus kita lakukan di aplikasi inti musim semi.sumber
@PostConstruct
dan@PreDestroy
saya menggunakan atributinitMethod
dandestroyMethod
dalam@Bean
anotasi. Jadi untuk contoh ini:@Bean(initMethod="init", destroyMethod="destroy")
.@PreDestroy
mungkin tidak diketahui oleh beberapa pengembang adalah, metode seperti itu hanya dipanggil untuk kacang dengan cakupan Singleton. Pengembang harus mengelola bagian pembersihan siklus hidup kacang untuk cakupan lainAda banyak cara untuk mematikan aplikasi pegas. Salah satunya adalah memanggil close () di
ApplicationContext
:Pertanyaan Anda menyarankan Anda ingin menutup aplikasi Anda dengan melakukan
Ctrl+C
, yang sering digunakan untuk menghentikan perintah. Pada kasus ini...Penggunaan
endpoints.shutdown.enabled=true
bukanlah resep terbaik. Ini berarti Anda mengekspos titik akhir untuk menghentikan aplikasi Anda. Jadi, tergantung pada kasus penggunaan dan lingkungan Anda, Anda harus mengamankannya ...Ctrl+C
harus bekerja dengan baik dalam kasus Anda. Saya menganggap masalah Anda disebabkan oleh ampersand (&) Penjelasan selengkapnya:Konteks Aplikasi Musim Semi mungkin telah mendaftarkan hook shutdown dengan runtime JVM. Lihat dokumentasi ApplicationContext .
Saya tidak tahu apakah Spring Boot mengkonfigurasi hook ini secara otomatis seperti yang Anda katakan. Saya berasumsi demikian.
Aktif
Ctrl+C
, shell Anda mengirimkanINT
sinyal ke aplikasi latar depan. Artinya "tolong hentikan eksekusi Anda". Aplikasi dapat menjebak sinyal ini dan melakukan pembersihan sebelum penghentiannya (pengait didaftarkan oleh Spring), atau mengabaikannya (buruk).nohup
adalah perintah yang menjalankan program berikut dengan perangkap untuk mengabaikan sinyal HUP. HUP digunakan untuk menghentikan program ketika Anda menutup telepon (tutup koneksi ssh Anda misalnya). Selain itu, ia mengalihkan keluaran untuk menghindari blok program Anda pada TTY yang menghilang.nohup
TIDAK mengabaikan sinyal INT. Jadi TIDAK mencegahCtrl+C
untuk bekerja.Saya berasumsi bahwa masalah Anda disebabkan oleh tanda & (&), bukan oleh nohup.
Ctrl+C
mengirimkan sinyal ke proses latar depan. Tanda ampersand menyebabkan aplikasi Anda berjalan di latar belakang. Satu solusi: lakukanGunakan
kill -9
ataukill -KILL
buruk karena aplikasi (di sini JVM) tidak dapat menjebaknya untuk dihentikan dengan baik.Solusi lain adalah mengembalikan aplikasi Anda di latar depan. Kemudian
Ctrl+C
akan berhasil. Lihat kontrol Bash Job, lebih tepatnya difg
.sumber
Gunakan
exit()
metode statis di kelas SpringApplication untuk menutup aplikasi boot musim semi Anda dengan baik.sumber
Spring Boot sekarang mendukung penonaktifan anggun (saat ini dalam versi pra-rilis, 2.3.0.BUILD-SNAPSHOT)
Anda dapat mengaktifkannya dengan:
https://docs.spring.io/spring-boot/docs/2.3.0.BUILD-SNAPSHOT/reference/html/spring-boot-features.html#boot-features-graceful-shutdown
sumber
Jika Anda menggunakan maven, Anda dapat menggunakan plugin assembler Aplikasi Maven .
Daemon mojo (yang menyertakan JSW ) akan menampilkan skrip shell dengan argumen start / stop. Ini
stop
akan mematikan / mematikan aplikasi Spring Anda dengan anggun.Skrip yang sama dapat digunakan untuk menggunakan aplikasi maven Anda sebagai layanan linux.
sumber
Jika Anda berada di lingkungan linux, yang harus Anda lakukan adalah membuat symlink ke file .jar Anda dari dalam /etc/init.d/
Kemudian Anda dapat memulai aplikasi seperti layanan lainnya
Untuk menutup aplikasi
Dengan cara ini, aplikasi tidak akan berhenti saat Anda keluar dari terminal. Dan aplikasi akan mati dengan baik dengan perintah stop.
sumber