Vscode debug GoLang micro-services in Docker

English @medium

查一般的 bug凰兑,我更習(xí)慣直接加打印,能快速定位問(wèn)題审丘,遠(yuǎn)比斷點(diǎn)調(diào)試方便的多吏够。但遇到一些復(fù)雜、或是涉及第三方類(lèi)庫(kù)時(shí)滩报,卻不得不需要添加斷點(diǎn)逐步跟蹤邏輯锅知。

使用 golang 開(kāi)發(fā)的微服務(wù),全部是直接運(yùn)行在 docker 容器里的脓钾,想要調(diào)試并不是一件簡(jiǎn)單的事情售睹,這時(shí)候我們就需要 Remote Debug (遠(yuǎn)程調(diào)試)

  • vscode - 代碼編輯器
  • ms-vscode.go - vscode 支持 Go 語(yǔ)言的插件
  • delve - Golang 調(diào)試工具,支持遠(yuǎn)程調(diào)試
  • Makefile - 封裝指令的合集
  • alpine - 迷你 Docker 系統(tǒng)鏡像可训,只有 5MB

啟動(dòng)容器

通過(guò)MakefileDockerfile編譯鏡像和運(yùn)行 Docker 容器昌妹,我的方式是在本地(MacOS)上編譯好 Linux 的可執(zhí)行文件,拷貝到用 alpine 小鏡像創(chuàng)建的容器里握截。也可以選擇用 golang 鏡像飞崖,拷貝源碼進(jìn)去。

  1. 配置 Makefile
  • 注意在編譯應(yīng)用程序時(shí)需要谨胞,通過(guò)添加 -gcflags "all=-N -l" 生成支持 Debug 的包
  • 運(yùn)行容器時(shí)需要通過(guò)參數(shù) --security-opt="seccomp=unconfined" --cap-add=SYS_PTRACE 關(guān)閉容器的安全限制
  • 運(yùn)行時(shí)需要把 dlv 監(jiān)聽(tīng)的端口暴露出來(lái) -p 20000:20000固歪,以便 vscode 調(diào)試程序去連接
NAME := account
IMAGE := $(NAME)-service

# 編譯鏡像
build-debug:
    # 清理廢棄的image (按需開(kāi)啟)
    docker image prune -f

    # 編譯Linux版 dlv可執(zhí)行文件
    GOOS=linux GOARCH=amd64 go build github.com/go-delve/delve/cmd/dlv

    # 編譯Linux版 應(yīng)用可執(zhí)行文件
    GOOS=linux GOARCH=amd64 go build -gcflags "all=-N -l"

    # 指定Dockerfile 生成鏡像
    docker build -f Dockerfile.debug -t $(IMAGE) .

    # 清理掉生成的可執(zhí)行文件
    rm -f $(NAME) dlv

# 運(yùn)行容器
run-debug:
    # my-docker-network 是我的Docker network,所有的微服務(wù)都在這個(gè)網(wǎng)絡(luò)里胯努,可以直接互連
    docker run --rm --name $(IMAGE) \
    --network my-docker-network \
    --security-opt="seccomp=unconfined" --cap-add=SYS_PTRACE \
    -p 20000:20000 \
    $(IMAGE)


debug: build-debug run-debug
  1. 配置 Dockerfile.debug

容器啟動(dòng)入口為 ./dlv --listen=:20000 --headless=true --api-version=2 --log=true exec ./account

  • ./代表 WORKDIR 的/app目錄牢裳,dlv、account 可執(zhí)行文件我們通過(guò) Dockerfile 都已經(jīng)添加到這個(gè)目錄里了
  • --listen=:20000 dlv 服務(wù)綁定的端口
  • --headless=true 調(diào)試服務(wù)器叶沛,無(wú) ui 模式
  • --api-version=2 服務(wù)提供的 API 版本
  • --log=true 開(kāi)啟日志贰健,否則只能看到應(yīng)用日志,沒(méi)有 dlv 自身的日志
  • exec ./account 準(zhǔn)備執(zhí)行的程序恬汁,這個(gè)程序必須支持 Debug

exec對(duì)應(yīng)的還有另外一個(gè)指令: debug,直接調(diào)試源碼可以用

FROM alpine:3.9

# 應(yīng)用程序需要這個(gè)組件來(lái)支持請(qǐng)求HTTPS的網(wǎng)址
RUN apk add ca-certificates

RUN mkdir /app
WORKDIR /app

ADD dlv account config.yml ./

ENTRYPOINT ["./dlv", "--listen=:20000", "--headless=true", "--api-version=2", "--log=true", "exec", "./account"]
  1. 運(yùn)行容器

會(huì)發(fā)現(xiàn)沒(méi)有應(yīng)用啟動(dòng)日志辜伟,是因?yàn)槲⒎?wù)在此時(shí)還未被拉起氓侧,只是關(guān)聯(lián)好了

$ make debug
...
2019-05-08T13:03:23Z info layer=debugger launching process with args: [./account]
API server listening at: [::]:20000

Vscode 配置及斷點(diǎn)調(diào)試

  1. 配置啟動(dòng)文件
  • mode remote 開(kāi)啟遠(yuǎn)程模式

  • hostport 配置成 dlv 暴露出的服務(wù)器地址

  • program 配置成本地對(duì)應(yīng)的源碼 main 文件

  • launch.json

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Remote Debug",
      "type": "go",
      "request": "launch",
      "mode": "remote",
      "remotePath": "",
      "port": 10001,
      "host": "127.0.0.1",
      "program": "${workspaceRoot}/cmd/account/main.go",
      "showLog": true,
      "env": {},
      "args": []
    }
  ]
}
  1. 點(diǎn)擊開(kāi)始調(diào)試导狡,應(yīng)用才開(kāi)始運(yùn)行约巷,所以可以看出是 vscode 客戶(hù)端通知 dlv 服務(wù)器啟動(dòng)應(yīng)用的
  2. 這時(shí)候我們?cè)?vscode 里創(chuàng)建一個(gè)斷點(diǎn),服務(wù)器會(huì)出現(xiàn)對(duì)應(yīng)的日志旱捧。
2019-05-08T13:06:03Z debug layer=debugger halting
2019-05-08T13:06:03Z info layer=debugger created breakpoint: ...
2019-05-08T13:06:03Z debug layer=debugger continuing
  1. 接下來(lái)就和在本地調(diào)試程序是一樣的了独郎。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末踩麦,一起剝皮案震驚了整個(gè)濱河市谓谦,隨后出現(xiàn)的幾起案子反粥,更是在濱河造成了極大的恐慌,老刑警劉巖郑气,帶你破解...
    沈念sama閱讀 212,816評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件巩螃,死亡現(xiàn)場(chǎng)離奇詭異爷耀,居然都是意外死亡歹叮,警方通過(guò)查閱死者的電腦和手機(jī)咆耿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)慰技,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)吻商,“玉大人乌叶,你說(shuō)我怎么就攤上這事。” “怎么了晰奖?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,300評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵蛔外,是天一觀的道長(zhǎng)豹爹。 經(jīng)常有香客問(wèn)我,道長(zhǎng)孩等,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,780評(píng)論 1 285
  • 正文 為了忘掉前任蹬癌,我火速辦了婚禮权她,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘逝薪。我一直安慰自己伴奥,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,890評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布翼闽。 她就那樣靜靜地躺著,像睡著了一般洲炊。 火紅的嫁衣襯著肌膚如雪感局。 梳的紋絲不亂的頭發(fā)上尼啡,一...
    開(kāi)封第一講書(shū)人閱讀 50,084評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音询微,去河邊找鬼崖瞭。 笑死,一個(gè)胖子當(dāng)著我的面吹牛撑毛,可吹牛的內(nèi)容都是我干的书聚。 我是一名探鬼主播,決...
    沈念sama閱讀 39,151評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼藻雌,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼雌续!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起胯杭,我...
    開(kāi)封第一講書(shū)人閱讀 37,912評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤驯杜,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后做个,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體鸽心,經(jīng)...
    沈念sama閱讀 44,355評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,666評(píng)論 2 327
  • 正文 我和宋清朗相戀三年居暖,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了顽频。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,809評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡太闺,死狀恐怖糯景,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情跟束,我是刑警寧澤莺奸,帶...
    沈念sama閱讀 34,504評(píng)論 4 334
  • 正文 年R本政府宣布,位于F島的核電站冀宴,受9級(jí)特大地震影響灭贷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜略贮,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,150評(píng)論 3 317
  • 文/蒙蒙 一甚疟、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧逃延,春花似錦政冻、人聲如沸万哪。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)拉庶。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背俐末。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,121評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留奄侠,地道東北人卓箫。 一個(gè)月前我還...
    沈念sama閱讀 46,628評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像垄潮,于是被迫代替她去往敵國(guó)和親烹卒。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,724評(píng)論 2 351