真的香!使用 VSCode 進(jìn)行遠(yuǎn)程開(kāi)發(fā)調(diào)試

對(duì)于大型的 Golang 項(xiàng)目往往我都會(huì)使用 Goland 這樣的專業(yè) IDE,但是由于我本地開(kāi)發(fā)環(huán)境硬件資源偏低,不能很順暢的使用 Goland,這個(gè)時(shí)候我們可以考慮使用 VSCode 來(lái)代替 Goland,而且 VSCode 還支持遠(yuǎn)程開(kāi)發(fā),所以我索性將開(kāi)發(fā)環(huán)境放在遠(yuǎn)程機(jī)器上,然后用 VSCode 遠(yuǎn)程開(kāi)發(fā)模式進(jìn)行連接,最主要的是大部分我們的項(xiàng)目都是直接跑在 Linux 上面的,這個(gè)時(shí)候我們就可以直接在 VSCode 中運(yùn)行 Linux 環(huán)境下面的應(yīng)用,而且我們還可以很好地進(jìn)行調(diào)試,也降低了本地的資源占用。
遠(yuǎn)程配置
VSCode 的 Remote 功能由三個(gè)插件組成,分別實(shí)現(xiàn)三種不同場(chǎng)景的遠(yuǎn)程開(kāi)發(fā)。
Remote - SSH:利用 SSH 連接遠(yuǎn)程主機(jī)進(jìn)行開(kāi)發(fā)。 Remote - Container:連接當(dāng)前機(jī)器上的容器進(jìn)行開(kāi)發(fā)。 Remote - WSL:在Windows 10上,連接子系統(tǒng)(Windows Subsystem for Linux)進(jìn)行開(kāi)發(fā)。
我們這里使用 SSH 模式進(jìn)行配置,SSH 模式的原理如下圖所示:

首先我們這里在本地環(huán)境 Mac 上安裝上 VSCode,遠(yuǎn)程開(kāi)發(fā)的機(jī)器 IP 為 192.168.31.104,配置該節(jié)點(diǎn)可以本地通過(guò) SSH 遠(yuǎn)程連接。然后在 VSCode 中安裝 Remote SSH 插件:

安裝了 Remote - SSH 擴(kuò)展后,你會(huì)在最左邊看到一個(gè)新的狀態(tài)欄圖標(biāo)。

遠(yuǎn)程狀態(tài)欄圖標(biāo)可以快速顯示 VS Code 在哪個(gè)上下文中運(yùn)行(本地或遠(yuǎn)程),點(diǎn)擊該圖標(biāo)或者點(diǎn)擊 F1 按鍵然后輸入remote-ssh 便會(huì)彈出 Remote-SSH 的相關(guān)命令。

選擇 "Remote-SSH: Connect to Host" 命令,然后按以下格式輸入遠(yuǎn)程主機(jī)的連接信息,連接到主機(jī):user@hostname,然后根據(jù)提示輸入登錄的密碼。
VSCode 將打開(kāi)一個(gè)新窗口,然后你會(huì)看到 "VSCode 服務(wù)器 "正在 SSH 主機(jī)上初始化的通知,一旦 VSCode 服務(wù)器安裝在遠(yuǎn)程主機(jī)上,它就可以運(yùn)行擴(kuò)展并與你的本地 VSCode 實(shí)例通信了。通過(guò)查看狀態(tài)欄中的指示器,可以知道已連接到虛擬機(jī)了,它顯示的是你的虛擬機(jī)的主機(jī)名。

Remote-SSH 擴(kuò)展還在你的活動(dòng)欄上添加了一個(gè)新的圖標(biāo),點(diǎn)擊它將打開(kāi)遠(yuǎn)程瀏覽器。從下拉菜單中,可以選擇 SSH 目標(biāo),在這里你可以配置你的 SSH 連接。

一旦你連接到你的 SSH 主機(jī),你就可以與遠(yuǎn)程機(jī)器上的文件進(jìn)行交互l ,如果你打開(kāi)集成終端(`?``),你會(huì)發(fā)現(xiàn)現(xiàn)在我們是在遠(yuǎn)程的 Linux 下面了。

現(xiàn)在我們可以使用 bash shell 瀏覽遠(yuǎn)程主機(jī)上的文件系統(tǒng),還可以使用 "文件">"打開(kāi)文件夾" 瀏覽和打開(kāi)遠(yuǎn)程主目錄上的文件夾。

此外,如果我們開(kāi)發(fā)的是 WEB 應(yīng)用,為了能夠?yàn)g覽到遠(yuǎn)程主機(jī)上的應(yīng)用,我們可以利用另一個(gè)端口轉(zhuǎn)發(fā)的功能來(lái)實(shí)現(xiàn)。
環(huán)境配置
現(xiàn)在我們已經(jīng)可以在 VSCode 中進(jìn)行遠(yuǎn)程開(kāi)發(fā)了,接下來(lái)我們以開(kāi)源項(xiàng)目 KinD 為例來(lái)說(shuō)明如何進(jìn)行遠(yuǎn)程調(diào)試。
KinD 是一個(gè)使用 Docker 容器
節(jié)點(diǎn)運(yùn)行本地 Kubernetes 集群的工具,主要是為了測(cè)試 Kubernetes 本身而設(shè)計(jì)的,但也可以用于本地開(kāi)發(fā)或CI 測(cè)試。
首先在遠(yuǎn)程主機(jī)上 Clone 代碼(也可以直接通過(guò) VSCode Clone 操作):
cnych@ubuntu:~/Github$?git?clone?https://github.com/kubernetes-sigs/kind.git
cnych@ubuntu:~/Github$?git?checkout?v0.9.0
cnych@ubuntu:~/Github$?git?checkout?-b?dev
然后在 VSCode 中定位到該項(xiàng)目,打開(kāi)該項(xiàng)目。由于我們這是一個(gè) Golang 項(xiàng)目,當(dāng)然首先要做的是在遠(yuǎn)程主機(jī)上安裝 Golang 的環(huán)境。然后當(dāng)然需要在 VSCode 中安裝 Golang 的插件,但是要注意的是我們需要安裝到遠(yuǎn)程主機(jī)上,切換到 EXTENSIONS 頁(yè)面,輸入 Go,選擇 Go 插件,然后在插件頁(yè)面我們可以看到一個(gè) Install on SSH: 192.168.31.104 的按鈕,點(diǎn)擊這個(gè)按鈕按鈕就可以將該插件安裝到遠(yuǎn)程主機(jī)上:

安裝完成后,還需要安裝一些相關(guān)的命令行工具,可以查看 https://github.com/golang/vscode-go 了解相關(guān)信息。同樣在 VSCode 中輸入 F1 按鍵,然后輸入 Go 關(guān)鍵字,可以列出和 Go 相關(guān)的操作:

我們要做的是選擇第一條命令:Go: Install/Update Tools,選擇所有的命令行工具,點(diǎn)擊 OK 按鈕便會(huì)在遠(yuǎn)程主機(jī)上安裝這些工具:

不過(guò)需要注意的是這些工具或多或少需要一些科學(xué)方法才能下載成功,我們也可以手動(dòng)下載這些工具放到 GOBIN 目錄下面即可。

這些命令行工具配置完成后,我們就可以在項(xiàng)目中使用這些工具了,在 KinD 項(xiàng)目根目錄下面創(chuàng)建 .vscode 目錄,在目錄下面新建 settings.json 文件,該文件就是來(lái)配置 VSCode 的,我這里使用的配置信息如下所示,我們可以根據(jù)自己的實(shí)際需求進(jìn)行配置:
{
??"workbench.editor.enablePreview":?false,
??"editor.fontLigatures":?true,
??"editor.fontSize":?20,?
??"editor.fontFamily":?"'Ubuntu?Mono?derivative?Powerline'",
??"terminal.integrated.fontFamily":?"'Ubuntu?Mono?derivative?Powerline'",
??"terminal.integrated.fontSize":?17,
??"workbench.fontAliasing":?"antialiased",
??"go.inferGopath":?false,
??"go.autocompleteUnimportedPackages":?true,
??"go.useLanguageServer":?true,
??"go.lintTool":?"golangci-lint",
??"go.docsTool":?"godoc",
??"go.buildFlags":?[],
??"go.lintFlags":?[],
??"go.vetFlags":?[],
??"go.gocodePackageLookupMode":?"go",
??"go.gotoSymbol.includeImports":?true,
??"go.useCodeSnippetsOnFunctionSuggest":?true,
??"go.useCodeSnippetsOnFunctionSuggestWithoutType":?true,
??"go.formatTool":?"goreturns",?
??"go.gocodeAutoBuild":?false,
??"go.liveErrors":?{
??????"enabled":?true,
??????"delay":?0
??}
}
現(xiàn)在在 VSCode 終端的項(xiàng)目目錄下面執(zhí)行如下命令更新依賴:
cnych@ubuntu:~/Github$?export?GOPROXY="https://goproxy.cn"
cnych@ubuntu:~/Github$?go?mod?tidy
現(xiàn)在我們就可以在 VSCode 中查看項(xiàng)目了,可以快速跟蹤代碼,也有代碼提示,基本上 IDE 有的功能,在 VSCode 中都有:

不過(guò)對(duì)于大型 Golang 項(xiàng)目使用 VSCode 不方面的一個(gè)地方是不能快速定位到接口的實(shí)現(xiàn),因?yàn)?Golang 中的接口很可能有多個(gè)地方都有實(shí)現(xiàn),這點(diǎn) VSCode 就沒(méi)有 Goland 方便了,不過(guò)我們也還是可以使用快捷方式找到接口的實(shí)現(xiàn),我們可以將鼠標(biāo)定位到接口名稱或者接口方法聲明上,然后通過(guò)快捷鍵Cmd(Windows 下面是 Ctrl)+ F12 就可以找到對(duì)應(yīng)的實(shí)現(xiàn),當(dāng)然也可以通過(guò)右鍵查找所有實(shí)現(xiàn):

遠(yuǎn)程調(diào)試
現(xiàn)在我們已經(jīng)可以使用 Remote-SSH 插件開(kāi)發(fā)項(xiàng)目了,但是在開(kāi)發(fā)過(guò)程中或者學(xué)習(xí)開(kāi)源項(xiàng)目的時(shí)候往往少不了調(diào)試,特別是要想快速了解開(kāi)源項(xiàng)目的實(shí)現(xiàn),單步調(diào)試跟蹤代碼是非常好的一種方式,比如我們要來(lái)跟蹤下 KinD 是如何創(chuàng)建集群的,我們就可以在 KinD 創(chuàng)建集群的某些代碼片段上打上端點(diǎn),然后單步調(diào)試進(jìn)行跟蹤。
比較幸運(yùn)的時(shí)候 VSCode 就可以很好的來(lái)幫助我們進(jìn)行調(diào)試的操作。Golang 項(xiàng)目的調(diào)試是依賴 delve 這個(gè)工具的,上面安裝命令行工具的時(shí)候已經(jīng)安裝了,如果沒(méi)有安裝,我們可以使用如下方式進(jìn)行手動(dòng)安裝:
$?go?get?-u?github.com/go-delve/delve/cmd/dlv
安裝完成后需要配置調(diào)試工具,F(xiàn)1 輸入?Debug: Open launch.json?打開(kāi)?launch.json?文件。

如果第一次打開(kāi),會(huì)新建一個(gè)配置文件,默認(rèn)配置內(nèi)容如下所示:
{
?"version":?"0.2.0",
?"configurations":?[
??{
???"name":?"Launch",
???"type":?"go",
???"request":?"launch",
???"mode":?"auto",
???"program":?"${fileDirname}",
???"env":?{},
???"args":?[]
??}
?]
}
常見(jiàn)的配置屬性:

我們還可以在配置文件中使用一些內(nèi)置的變量:
${workspaceFolder}調(diào)試 VS Code 打開(kāi)工作空間的根目錄下的所有文件${file}調(diào)試當(dāng)前文件${fileDirname}調(diào)試當(dāng)前文件所在目錄下的所有文件
比如我們要調(diào)試 KinD 的創(chuàng)建集群的命令,對(duì)應(yīng)的 launch.json?文件內(nèi)容如下所示:
{
??"version":?"0.2.0",
??"configurations":?[
????{
??????"name":?"Debug?Kind",
??????"type":?"go",
??????"request":?"launch",
??????"mode":?"debug",
??????"host":?"127.0.0.1",
??????"port":?2345,
??????"program":?"${workspaceFolder}/main.go",
??????"cwd":?"${workspaceFolder}",
??????"env":?{},
???"args":?["create",?"cluster"]
????}
??]
}
然后在創(chuàng)建集群的代碼片段中打上端點(diǎn),比如在 pkg/cluster/internal/create/create.go 文件的 Cluster 函數(shù)中打上兩個(gè)端點(diǎn)(在左側(cè)點(diǎn)擊一下即可):

然后在左側(cè)切換到調(diào)試,點(diǎn)擊我們上面配置的 Debug Kind 按鈕(或者使用 F5 按鍵)即可開(kāi)始調(diào)試:

開(kāi)始調(diào)試后, delve 會(huì)在遠(yuǎn)程主機(jī)上啟動(dòng)一個(gè)無(wú)頭服務(wù),監(jiān)聽(tīng)在 2345 端口上,正常這個(gè)時(shí)候我們的程序會(huì)運(yùn)行到我們上面打的斷點(diǎn)位置停下來(lái):

這個(gè)時(shí)候我們可以看到已經(jīng)初始化的變量信息,在最上方也有調(diào)試的工具欄,當(dāng)然也有對(duì)應(yīng)的快捷鍵,F5:繼續(xù)、F10:?jiǎn)尾綀?zhí)行、F11:進(jìn)入函數(shù)內(nèi)部執(zhí)行,這幾個(gè)快捷鍵是最常用的,當(dāng)然如果你的快捷鍵有沖突我們可以直接使用上面的工具欄進(jìn)行操作。在操作的過(guò)程中產(chǎn)生的日志信息也會(huì)出現(xiàn)在 DEBUG CONSOLE 欄目下面。這樣我們就實(shí)現(xiàn)了遠(yuǎn)程調(diào)試的,對(duì)于開(kāi)源項(xiàng)目我們可以多使用單步調(diào)試去跟蹤代碼的執(zhí)行,這樣可以更快了解程序的執(zhí)行流程,當(dāng)然遠(yuǎn)程調(diào)試并不只是針對(duì) Golang 項(xiàng)目,其他語(yǔ)言的也同樣適用。
另外告訴大家一個(gè)好消息,優(yōu)點(diǎn)知識(shí)國(guó)慶中秋雙節(jié)課程優(yōu)惠活動(dòng)也已經(jīng)開(kāi)啟了,感興趣的同學(xué)可以掃描下發(fā)二維碼了解。
