亚洲成a人片在线观看www_二区免费视频_免费在线观看毛片_国产精品www爽爽爽视频_国产一区av在线_区美毛片

中國專業(yè)IT外包服務(wù)

用心服務(wù)每一天
IT之道-艾銻知道

您當(dāng)前位置: 主頁 > IT服務(wù) > 服務(wù)器服務(wù) >

服務(wù)器維護docker容器如何優(yōu)雅的終止詳解


2020-05-27 17:34 作者:艾銻無限 瀏覽量:

如何做好服務(wù)器維護?北京艾銻無限科技與你談?wù)処T人員必須知道的服務(wù)器維護信息

服務(wù)器維護過程中,我們?nèi)粘5捻椖慨?dāng)中,這是我們經(jīng)常需要面對和處理的問題:

 服務(wù)器維護場景A:假如我們打包在容器中的程序,提供HTTP方式的服務(wù),負(fù)責(zé)處理各種HTTP requests并返回結(jié)果,我們必然希望在容器被停掉的時候,能夠讓程序有時間把已經(jīng)在處理中的請求繼續(xù)處理完畢,并返回結(jié)果給客戶端。

服務(wù)器維護場景B:又比如我們打包在容器中的程序,負(fù)責(zé)寫入數(shù)據(jù)到某個數(shù)據(jù)文件中,我們希望程序能夠在容器被停掉的時候,有時間把內(nèi)存中緩存的數(shù)據(jù)持久化到存儲設(shè)備中,以防數(shù)據(jù)丟失。

服務(wù)器維護場景C:再比如現(xiàn)在流行的微服務(wù)架構(gòu)中,一般會有服務(wù)發(fā)現(xiàn)的機制,也即每一個微服務(wù)在啟動之后,都會主動把自己的地址信息注冊到服務(wù)發(fā)現(xiàn)模塊當(dāng)中,讓其他的服務(wù)可以知道自己的存在。而在容器被停掉的時候,微服務(wù)需要即時從服務(wù)發(fā)現(xiàn)模塊中注銷自己,以防止從API Gateway而來的請求被錯
誤的路由到了已經(jīng)被停止掉的微服務(wù)。

如上的各種場景中,都要求打包在容器中的應(yīng)用程序能夠被優(yōu)雅的終止(也即gracefully shutdown),這種gracefully shutdown的方式,允許程序在容器被停止的時候,有一定時間做一些后續(xù)處理操作,這也是我們需要進一步探討的話題。

服務(wù)器維護提示:docker stop 與 docker kill 的區(qū)別

Docker本身提供了兩種終止容器運行的方式,即docker stop與docker kill。

服務(wù)器維護要點:docker stop

先來說說docker stop吧,當(dāng)我們用docker stop命令來停掉容器的時候,docker默認(rèn)會允許容器中的應(yīng)用程序有10秒的時間用以終止運行。所以我們查看docker stop命令幫助的時候,會有如下的提示:

1

2

3

4

5

6
→ docker stop --help

Usage: docker stop [OPTIONS] CONTAINER [CONTAINER...]

Stop one or more running containers

Options:

  --help  Print usage

 -t, --time int Seconds to wait for stop before killing it (default 10)

在docker stop命令執(zhí)行的時候,會先向容器中PID為1的進程發(fā)送系統(tǒng)信號SIGTERM,然后等待容器中的應(yīng)用程序終止執(zhí)行,如果等待時間達(dá)到設(shè)定的超時時間,或者默認(rèn)的10秒,會繼續(xù)發(fā)送SIGKILL的系統(tǒng)信號強行kill掉進程。在容器中的應(yīng)用程序,可以選擇忽略和不處理SIGTERM信號,不過一旦達(dá)到超時時間,程序就會被系統(tǒng)強行kill掉,因為SIGKILL信號是直接發(fā)往系統(tǒng)內(nèi)核的,應(yīng)用程序沒有機會去處理它。在使用docker stop命令的時候,我們唯一能控制的是超時時間,比如設(shè)置為20秒超時:

1
docker stop --time=20 container_name

服務(wù)器維護要點:docker kill

接著我們來看看docker kill命令,默認(rèn)情況下,docker kill命令不會給容器中的應(yīng)用程序有任何gracefully shutdown的機會。它會直接發(fā)出SIGKILL的系統(tǒng)信號,以強行終止容器中程序的運行。通過查看docker kill命令的幫助,我們可以看到,除了默認(rèn)發(fā)送SIGKILL信號外,還允許我們發(fā)送一些自定義的系統(tǒng)信號:

1

2

3

4

5
6

→ docker kill --help

Usage: docker kill [OPTIONS] CONTAINER [CONTAINER...]

Kill one or more running containers

Options:
  
--help   Print usage
 
-s, --signal string Signal to send to the container (default "KILL")

比如,如果我們想向docker中的程序發(fā)送SIGINT信號,我們可以這樣來實現(xiàn):

1 docker kill --signal=SIGINT container_name

與docker stop命令不一樣的地方在于,docker kill沒有任何的超時時間設(shè)置,它會直接發(fā)送SIGKILL信號,以及用戶通過signal參數(shù)指定的其他信號。

其實不難看出,docker stop命令,更類似于Linux系統(tǒng)中的kill命令,二者都是發(fā)送系統(tǒng)信號SIGTERM。而docker kill命令,更像是Linux系統(tǒng)中的kill -9或者是kill -SIGKILL命令,用來發(fā)送SIGKILL信號,強行終止進程。

服務(wù)器維護提示:在程序中接收并處理信號

了解了docker stop與docker kill的區(qū)別,我們能夠知道,docker kill適合用來強行終止程序并實現(xiàn)快速停止容器。而如果希望程序能夠gracefully shutdown的話,docker stop才是不二之選。這樣,我們可以讓程序在接收到SIGTERM信號后,有一定的時間處理、保存程序執(zhí)行現(xiàn)場,優(yōu)雅的退出程序。

接下來我們可以寫一個簡單的Go程序來實現(xiàn)信號的接收與處理,程序在啟動過后,會一直阻塞并監(jiān)聽系統(tǒng)信號,直到監(jiān)測到對應(yīng)的系統(tǒng)信號后,輸出控制臺并退出執(zhí)行。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// main.go

package main

import (

 "fmt"

 "os"

 "os/signal"

 "syscall"

)

func main() {

 fmt.Println("Program started...")

 ch := make(chan os.Signal, 1)

 signal.Notify(ch, syscall.SIGTERM)

 s := <-ch

 if s == syscall.SIGTERM {

 fmt.Println("SIGTERM received!")

 //Do something...

 }

 fmt.Println("Exiting...")
}

接下來服務(wù)器維護要點:使用交叉編譯的方式來編譯程序,讓程序可以在Linux下運行:

1
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o graceful
 

編譯好之后,我們還需要打包程序到容器中運行。于是,我們還得有個Dockerfile。在這里,我們選擇使用體積小又輕盈的alpine鏡像作為基礎(chǔ)鏡像,打包這個Go程序:

1
2
3
4
from alpine:latest

MAINTAINER Timothy

ADD graceful /graceful

CMD ["/graceful"]
 
服務(wù)器維護要點:這里需要避開的一個坑,是Dockerfile中CMD命令的用法。

服務(wù)器維護要點:CMD命令有兩種方式:

1 CMD /graceful

使用 CMD command param1 param2 這種方式,其實是以shell的方式運行程序。最終程序被執(zhí)行時,類似于/bin/sh -c的方式運行了我們的程序,這樣會導(dǎo)致/bin/sh以PID為1的進程運行,而我們的程序只不過是它fork/execs出來的子進程而已。前面我們提到過docker stop的SIGTERM信號只是發(fā)送給容器中PID為1的進程,而這樣,我們的程序就沒法接收和處理到信號了。

1 CMD [“/graceful”]

使用 CMD [“executable”,”param1”,”param2”] 這種方式啟動程序,才是我們想要的,這種方式執(zhí)行和啟動時,我們的程序會被直接啟動執(zhí)行,而不是以shell的方式,這樣我們的程序就能以PID=1的方式開始執(zhí)行了。

話題轉(zhuǎn)回來,我們開始執(zhí)行容器構(gòu)建操作,打包程序:

1 docker build -t registry.xiaozhou.net/graceful:latest .

 

打包過后的鏡像,才6MB左右:

1
2
3
λ Timothy [workspace/src/graceful] → docker images

REPOSITORY            TAG     IMAGE ID   CREATED    SIZE

registry.xiaozhou.net/graceful       latest    b2210a85ca55  20 hours ago  6.484 MB
 

啟動并運行容器:

1 λ Timothy [workspace/src/graceful] → docker run -d --name graceful b2210a85

查看容器運行狀態(tài):

1
2
3

λ Timothy [workspace/src/graceful] → docker ps -a

CONTAINER ID  IMAGE    COMMAND    CREATED    STATUS    PORTS    NAMES

fd18eedafd16  b221    "/graceful"   3 seconds ago  Up 2 seconds       graceful

查看容器輸出,能看到程序已經(jīng)正常啟動:

1
2
λ Timothy [workspace/src/graceful] → docker logs graceful

Started...

服務(wù)器維護要點:接著我們要使用docker stop大法,看程序能否響應(yīng)SIGTERM信號:

1
2
λ Timothy [workspace/src/graceful] → docker stop graceful

graceful

最后,查看容器的日志,檢驗輸出:

1
2
3
4
λ Timothy [workspace/src/graceful] → docker logs graceful

Started...

SIGTERM received!

Exiting...
 
以上內(nèi)容為北京艾銻無限科技發(fā)展有限公司IT外包服務(wù)公司為大家提供的服務(wù)器維護小知識,更多內(nèi)容請關(guān)注:www.bjitwx.com。

相關(guān)文章

IT外包服務(wù)
二維碼 關(guān)閉
主站蜘蛛池模板: 精品久久久久久中文字幕一区二区 | 国产综合久久一区二区三区 | 天天操天天色综合 | 国产区精品在线观看 | 亚洲国产成人一区二区三区 | 99re热视频这里只精品 | 国产区精品区 | 国产成人无码A区视频 | 国产精品推荐视频一区二区 | 久久久二区 | 欧洲乱码伦视频免费国产 | 国产成人a高清视频 | 亚洲欧美日韩另类国产第一 | 国产99热| 亚洲va欧美va国产va黑人 | 免费观看黄色片在线观看 | 欧美国产精品粉嫩在线播放 | 久久亚洲国产精品一区二区 | 色戒网站 | 超粉嫩00无码福利视频 | 国产综合日韩精品 | 亚洲精品无码久久久久久久久久久久久 | 国产精品久久久久久久久亚洲美女 | 无码丰满熟妇一区二区密臀 | CHINESE性内射高清国产 | 2020国产在线拍揄自揄视频 | 久久女 | 国产成人精品一区二三区在线观看 | 99国产一区二区精品久久 | 国产四虎 | 日韩精品中文字幕在线观看 | 国产精品视频第一区二区三区 | 国产超碰人人做人人爱ⅴa 国产精品1024在线永久免费 | aⅴ色国产 欧美 | 亚洲欧美综合在线一区 | 亚洲性区 | 99精品国产一区二区三区不卡 | 国产美女裸露免费看视频 | 中文字幕久久熟女蜜桃 | 欧美精品三区 | 亚洲va中文在线播放免费 |