本篇文章給大家分享的是有關(guān)springboot項目在docker容器中該如何關(guān)閉,小編覺得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
成都創(chuàng)新互聯(lián)公司自成立以來,一直致力于為企業(yè)提供從網(wǎng)站策劃、網(wǎng)站設(shè)計、成都做網(wǎng)站、成都網(wǎng)站制作、電子商務(wù)、網(wǎng)站推廣、網(wǎng)站優(yōu)化到為企業(yè)提供個性化軟件開發(fā)等基于互聯(lián)網(wǎng)的全面整合營銷服務(wù)。公司擁有豐富的網(wǎng)站建設(shè)和互聯(lián)網(wǎng)應(yīng)用系統(tǒng)開發(fā)管理經(jīng)驗、成熟的應(yīng)用系統(tǒng)解決方案、優(yōu)秀的網(wǎng)站開發(fā)工程師團(tuán)隊及專業(yè)的網(wǎng)站設(shè)計師團(tuán)隊。
在我看來所謂的優(yōu)雅關(guān)閉,就是在系統(tǒng)關(guān)閉時,預(yù)留一些時間,讓你有機(jī)會來善后一些事情
是否所有項目都需要優(yōu)雅關(guān)閉?那也不一定,畢竟所謂的優(yōu)雅關(guān)閉,另一面就意味這關(guān)閉得慢,因此項目的優(yōu)雅關(guān)閉得看項目的核心程度,換言之就是看該項目處理的數(shù)據(jù)是不是核心數(shù)據(jù),其實(shí)項目的最終本質(zhì),是對數(shù)據(jù)的處理。
通用的方法是通過進(jìn)程接收到系統(tǒng)發(fā)送信號變量來實(shí)現(xiàn),什么是信號變量,可以參考如下鏈接 https://www.cnblogs.com/liuhouhou/p/5400540.html
com.github.timpeeters spring-boot-graceful-shutdown X.X.X
通過引入這個jar,并且在項目的application.yml文件配置
graceful: shutdown: enabled: true
只需兩步就可實(shí)現(xiàn)優(yōu)雅關(guān)閉。當(dāng)項目進(jìn)行關(guān)閉時,觀察日志,會發(fā)現(xiàn)有如下輸出
spring-boot-graceful-shutdown目前支持的springboot版本如下
其實(shí)現(xiàn)流程
更多詳細(xì)教程可以參考如下鏈接 https://github.com/timpeeters/spring-boot-graceful-shutdown
server: # 開啟優(yōu)雅關(guān)閉,默認(rèn):IMMEDIATE,立即關(guān)閉 shutdown: graceful spring: lifecycle: # 配置優(yōu)雅關(guān)閉寬限時間,即項目在30s都沒處理完,則進(jìn)行強(qiáng)制關(guān)閉 timeout-per-shutdown-phase: 30s
其關(guān)閉效果如下
2021-01-15 10:52:04.063 INFO 39004 --- [extShutdownHook] o.s.b.w.e.tomcat.GracefulShutdown : Commencing graceful shutdown. Waiting for active requests to complete 2021-01-15 10:52:04.138 INFO 39004 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient : DiscoveryClient_HELLO-LOCAL/hello-local:172.17.45.115:8080 - registration status: 204 2021-01-15 10:52:04.605 INFO 39004 --- [tomcat-shutdown] o.s.b.w.e.tomcat.GracefulShutdown : Graceful shutdown complete c.netflix.discovery.TimedSupervisorTask : task supervisor shutting down, can't accept the task
如果在Dockerfile做如下配置
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ]
是沒法實(shí)現(xiàn)優(yōu)雅關(guān)閉的效果。其原因是使用 docker stop 關(guān)閉容器時, 只有 init(pid 1)進(jìn)程能收到中斷信號, 如果容器的pid 1 進(jìn)程是 sh 進(jìn)程, 它不具備轉(zhuǎn)發(fā)結(jié)束信號到它的子進(jìn)程的能力, 所以我們真正的java程序得不到中斷信號, 也就不能實(shí)現(xiàn)優(yōu)雅關(guān)閉. 解決思路是: 讓pid 1 進(jìn)程具備轉(zhuǎn)發(fā)終止信號, 或者將 java 程序配成 pid 1 進(jìn)程. 因此只需對Dockerfile做如下改造就行
ENTRYPOINT [ "sh", "-c", "exec java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ]
其實(shí)就是在java前邊加上exec即可。其實(shí)現(xiàn)機(jī)理可以參考如下鏈接 https://spring.io/guides/topicals/spring-boot-docker
1、配置preStop Hook鉤子
preStop Hook 是一個發(fā)送到 Pod 中的容器特殊命令或 Http 請求。如果您的應(yīng)用程序在接收 SIGTERM 時沒有正常關(guān)閉,您可以使用 preStop Hook 來觸發(fā)正常關(guān)閉。接收 SIGTERM 時大多數(shù)程序都會正常關(guān)閉,但如果您使用的是第三方代碼或管理的系統(tǒng)無法控制,則 preStop Hook 是在不修改應(yīng)用程序的情況下觸發(fā)正常關(guān)閉的好方法。
2、適當(dāng)延長terminationGracePeriodSeconds時間
terminationGracePeriodSeconds這玩意的意思直接看如下
其配置參考如下
apiVersion: apps/v1 kind: Deployment metadata: namespace: dev name: hello labels: app: hello spec: replicas: 3 selector: matchLabels: app: hello template: metadata: labels: app: hello spec: imagePullSecrets: - name: default-secret containers: - name: hello image: {{images}} ports: - containerPort: 8080 lifecycle: preStop: httpGet: port: 8080 path: 你要關(guān)閉時執(zhí)行的動作 terminationGracePeriodSeconds: 60
優(yōu)雅關(guān)閉正常都是會配置一定的處理時間,超過該時間沒處理完,就會進(jìn)行強(qiáng)殺。因此對于核心業(yè)務(wù),我們還得考慮萬一進(jìn)行強(qiáng)殺時,還要考慮是否需要對業(yè)務(wù)進(jìn)行補(bǔ)償操作
以上就是springboot項目在docker容器中該如何關(guān)閉,小編相信有部分知識點(diǎn)可能是我們?nèi)粘9ぷ鲿姷交蛴玫降?。希望你能通過這篇文章學(xué)到更多知識。更多詳情敬請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。