日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Docker容器:如何讓應(yīng)用程序優(yōu)雅退出

docker容器:如何讓應(yīng)用程序優(yōu)雅退出

作者:云技術(shù)趣談 2021-07-15 09:47:20

云計(jì)算 伴隨著業(yè)務(wù)的不斷更新迭代,容器啟動(dòng)的和停止經(jīng)常發(fā)生,當(dāng)容器停止時(shí),如果容器內(nèi)的程序未執(zhí)行完,那么將會(huì)造成數(shù)據(jù)不完整,特別是一些分布式事務(wù),可能會(huì)導(dǎo)致數(shù)據(jù)不一致,為此,容器引入優(yōu)雅關(guān)閉功能。

創(chuàng)新互聯(lián)是專業(yè)的魏縣網(wǎng)站建設(shè)公司,魏縣接單;提供成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站、成都外貿(mào)網(wǎng)站建設(shè)公司,網(wǎng)頁設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行魏縣網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來合作!

伴隨著業(yè)務(wù)的不斷更新迭代,容器啟動(dòng)的和停止經(jīng)常發(fā)生,當(dāng)容器停止時(shí),如果容器內(nèi)的程序未執(zhí)行完,那么將會(huì)造成數(shù)據(jù)不完整,特別是一些分布式事務(wù),可能會(huì)導(dǎo)致數(shù)據(jù)不一致,為此,容器引入優(yōu)雅關(guān)閉功能。

在上一篇 能在容器里面kill -9殺死容器的文章中,已經(jīng)介紹了如何捕獲信號(hào),當(dāng)我們執(zhí)行docker stop命令后,docker會(huì)向容器中進(jìn)程ID為1的進(jìn)程發(fā)送SIGTERM(kill -15)信號(hào),當(dāng)?shù)却欢螘r(shí)間后程序仍然沒有退出后,將發(fā)送SIGKILL(kill -9)信號(hào)強(qiáng)制殺死進(jìn)程。等待時(shí)間可以通過參數(shù)設(shè)置

  
 
 
  1. # docker stop ----time=30 foo 

但如果使用docker kill命令的話,則不會(huì)有等待時(shí)間,直接發(fā)送SIGKILL信號(hào)。Kubernetes在容器關(guān)閉時(shí)候也是通過docker stop命令優(yōu)雅關(guān)閉容器,當(dāng)容器內(nèi)應(yīng)用接收到SIGTERM信號(hào)后將拒絕新的訪問請(qǐng)求并且執(zhí)行完未處理的任務(wù),回收占用的資源。下面通過一段Go的代碼舉例如何獲取SIGTERM信號(hào)并優(yōu)雅退出。

  
 
 
  1. term := make(chan os.Signal) 
  2. signal.Notify(term, os.Interrupt, syscall.SIGTERM) 
  3. cancel := make(chan struct{}) 
  4. select { 
  5. case <-term: 
  6.    level.Warn(logger).Log(“msg“, “Received SIGTERM, exiting gracefully...“) 
  7.   #執(zhí)行具體回收動(dòng)作 

如果其他編程語言也相似,但這里有個(gè)坑需要需要注意,由于Docker關(guān)閉時(shí)候只給進(jìn)程號(hào)是1的進(jìn)程發(fā)送信號(hào),也就是說如果應(yīng)用程序的進(jìn)程ID不是1,那么將不會(huì)收到信號(hào)Docker發(fā)出的信號(hào)。下面舉例說明,先看一個(gè)正常的JAVA程序:Kill.java 。

  
 
 
  1. class Kill { 
  2.     private static Thread main; 
  3.     public static void main(String[] a) throws Exception { 
  4.         Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { 
  5.             public void run() { 
  6.                 System.out.println("TERM"); 
  7.                 main.interrupt(); 
  8.                 for (int i = 0; i < 4; i++) { 
  9.                     System.out.println("busy"); 
  10.                     try { 
  11.                         Thread.sleep(1000); 
  12.                     } catch (Exception e) {} 
  13.                 } 
  14.                 System.out.println("exit"); 
  15.             } 
  16.         })); 
  17.         main = Thread.currentThread(); 
  18.         while (true) { 
  19.             Thread.sleep(1000); 
  20.             System.out.println("run"); 
  21.         } 
  22.     } 

執(zhí)行”Javac Kill.java“編譯代碼并打包到Docker鏡像中,Dockerfile如下:

  
 
 
  1. FROM openjdk:8-jre-alpine 
  2. ADD Kill*.class / 
  3. ENTRYPOINT ["java","Kill"] 

啟動(dòng)容器,進(jìn)入容器可以看到”java Kill“進(jìn)程號(hào)為1,當(dāng)執(zhí)行docker stop命令后程序?qū)⒔邮盏絋ERM信號(hào),并優(yōu)雅退出。然后我們?cè)傩薷囊幌翫ockerfile,添加一個(gè)啟動(dòng)腳本start.sh,腳本非常簡單就兩行,如下:

  
 
 
  1. #! /bin/sh 
  2. java Kill 

重新構(gòu)建鏡像并啟動(dòng),新的Dockerfile如下:

  
 
 
  1. FROM openjdk:8-jre-alpine 
  2. ADD Kill*.class / 
  3. ADD start.sh / 
  4. ENTRYPOINT ["sh","-c","/start.sh"] 

啟動(dòng)容器后,進(jìn)入容器會(huì)發(fā)現(xiàn),JAVA進(jìn)程的ID變成7,成為shell(進(jìn)程ID為1)的子進(jìn)程。

  
 
 
  1. # ps -ef 
  2. ID   USER     TIME  COMMAND 
  3. 1     root      0:00 {start.sh} /bin/sh /start.sh 
  4.      root      0:00 java Kill 

此時(shí)再次執(zhí)行docker stop命令,容器將不會(huì)收的TERM信號(hào),并在默認(rèn)的10秒優(yōu)雅關(guān)閉時(shí)間后,直接退出(其實(shí)是被SIGKILL直接干掉了)。所以當(dāng)需要優(yōu)雅退出時(shí)必須保證應(yīng)用程序的進(jìn)程ID為1。

那有沒有別的方法,能夠在保證PID不為1的時(shí)候也能優(yōu)雅退出呢?當(dāng)然可以,有兩種常見的辦法:

(1)我們可以在容器關(guān)閉前執(zhí)行prestop腳本,腳本里面首先動(dòng)態(tài)獲取JAVA進(jìn)程的ID,然后通過kill直接對(duì)這個(gè)進(jìn)程發(fā)送TERM信號(hào),從而優(yōu)雅關(guān)閉程序。如下所示:

  
 
 
  1. PID=`pidof  java` && kill -SIGTERM $PID。 
  2. (2)可以通過tini容器啟動(dòng)應(yīng)用,tini的作為ID為1的進(jìn)程,當(dāng)他收到信號(hào)后就會(huì)轉(zhuǎn)發(fā)信號(hào)給子進(jìn)程,那么子進(jìn)程就可以執(zhí)行優(yōu)雅退出操作了。而且tini本身還具有回收僵尸進(jìn)程的能力。 

(2)可以通過tini容器啟動(dòng)應(yīng)用,tini的作為ID為1的進(jìn)程,當(dāng)他收到信號(hào)后就會(huì)轉(zhuǎn)發(fā)信號(hào)給子進(jìn)程,那么子進(jìn)程就可以執(zhí)行優(yōu)雅退出操作了。而且tini本身還具有回收僵尸進(jìn)程的能力。


網(wǎng)站題目:Docker容器:如何讓應(yīng)用程序優(yōu)雅退出
本文地址:http://m.5511xx.com/article/cocdjsj.html