硬核調(diào)試實(shí)操 | 手把手帶你實(shí)現(xiàn) Serverless 斷點(diǎn)調(diào)試


作者:千風(fēng) (阿里云函數(shù)計(jì)算研發(fā)工程師)

在應(yīng)用開(kāi)發(fā)過(guò)程中,或者開(kāi)發(fā)完成后,若出現(xiàn)執(zhí)行結(jié)果不符合我們的預(yù)期時(shí),通常需要進(jìn)行一定的調(diào)試工作。但是在 Serverless 架構(gòu)下,調(diào)試工作往往會(huì)受到一些環(huán)境因素限制,如所開(kāi)發(fā)的應(yīng)用在本地是比較健康的、且符合預(yù)期的運(yùn)行,但是在 FaaS (Functions as a Service) 平臺(tái)上,出現(xiàn)了一些問(wèn)題;或者是在某些特殊的環(huán)境下,本地沒(méi)有辦法模擬線上環(huán)境,難以進(jìn)行項(xiàng)目的開(kāi)發(fā)和調(diào)試怎么辦?
概述
本文將借助 Serverless Devs 工具,對(duì)函數(shù)計(jì)算? (FC) 應(yīng)用的斷點(diǎn)調(diào)試步驟進(jìn)行詳細(xì)指導(dǎo),手把手帶你實(shí)現(xiàn) Serverless 的斷點(diǎn)調(diào)試,并從以下四個(gè)方面為你厘清 “硬核調(diào)試” 的脈絡(luò)步驟,干貨滿滿:
在 Serverless 應(yīng)用架構(gòu)下,調(diào)試能力往往是應(yīng)用開(kāi)發(fā)者所十分關(guān)注的問(wèn)題,它決定著程序的開(kāi)發(fā)效率。Hackernoon 在關(guān)于 Serverless (無(wú)服務(wù)器) 的業(yè)界調(diào)研報(bào)告指出:迄今為止,Debugging (調(diào)試) 仍舊是 Serverless 落地最大的痛點(diǎn)與挑戰(zhàn)。

報(bào)告《Top 5 Serverless Trends》:https://hackernoon.com/top-5-serverless-trends-in-2020-wd1m3t8g
調(diào)試能力主要包含兩種,一是運(yùn)行程序的能力;二是斷點(diǎn)調(diào)試能力。前者是調(diào)試的基礎(chǔ)能力,可以判幫助開(kāi)發(fā)者判斷程序能否正常運(yùn)行,驗(yàn)證程序運(yùn)行結(jié)果的正確性;后者是調(diào)試的高級(jí)能力,能夠幫助用戶(hù)方便定位到導(dǎo)致程序運(yùn)行出錯(cuò)或者不符合預(yù)期的位置。
為了能夠克服這些缺陷,將 Serverless 應(yīng)用調(diào)試做到開(kāi)箱即用,阿里云函數(shù)計(jì)算團(tuán)隊(duì)經(jīng)過(guò)一番探索,開(kāi)發(fā)出了一套業(yè)界創(chuàng)新的調(diào)試工具,全方位提供本地調(diào)試以及端云聯(lián)調(diào)能力。
詳情可點(diǎn)擊閱讀:創(chuàng)新推出 | Serverless 調(diào)試大殺器:端云聯(lián)調(diào)
本地調(diào)試:基于本地環(huán)境以及網(wǎng)絡(luò),依賴(lài)容器化技術(shù),對(duì) Serverless 應(yīng)用進(jìn)行擬運(yùn)行,從而達(dá)到調(diào)試的目的,具體操作文檔可參考。
https://github.com/devsapp/fc/blob/main/docs/zh/command/local.md
端云聯(lián)調(diào):基于本地環(huán)境,突破網(wǎng)絡(luò)限制,依賴(lài)容器化技術(shù),對(duì) Serverless 應(yīng)用進(jìn)行擬運(yùn)行,運(yùn)行時(shí)打通本地與云端網(wǎng)絡(luò)的壁壘,保證與云端資源的交互,使用文檔請(qǐng)參考。
https://github.com/devsapp/fc/blob/main/docs/zh/command/proxied.md
本文所提到的本地調(diào)試工具,均提供斷點(diǎn)調(diào)試能力,且與 Serverless 應(yīng)用程序開(kāi)發(fā)規(guī)范完全兼容,下面我們一起看一下關(guān)于斷點(diǎn)調(diào)試的具體操作步驟。
調(diào)試之旅
- 啟動(dòng) Serverless 應(yīng)用
- 啟動(dòng)斷點(diǎn)調(diào)試器
- 開(kāi)始斷點(diǎn)調(diào)試
- 結(jié)束斷點(diǎn)調(diào)試
「01」
前置操作
在開(kāi)始進(jìn)行調(diào)試之前,需要進(jìn)行一些前置操作,本文將前置操作分為通用前置操作以及端云聯(lián)調(diào)附加的前置操作:
1)通用前置操作:
安裝調(diào)試 IDE:可選的 IDE 有 VSCode、Pycharm 以及 Intellij 三種;
隨后在開(kāi)始使用這些功能之前,請(qǐng)安裝好調(diào)試工具: 這里我們需要安裝一下 Serverless Devs,具體的安裝方式參考文檔:
https://help.aliyun.com/document_detail/195474.html;
?熟悉新一代函數(shù)計(jì)算工具鏈的使用方式,可參考:
https://github.com/devsapp/fc
下載安裝 Docker:調(diào)試能力都需要依賴(lài) Docker,因此需要本地環(huán)境中有 Docker 工具,安裝方式請(qǐng)參考這里:
https://docs.docker.com/get-docker/
最后還需要注冊(cè)一個(gè)阿里云賬號(hào),使用 Serverless Devs 配置阿里云賬號(hào),具體配置方式可以參考這里。
https://help.aliyun.com/document_detail/295894.html
2)端云聯(lián)調(diào)附加的前置操作:
我們需要準(zhǔn)備一個(gè)阿里云賬號(hào),由于端云聯(lián)調(diào)涉及到輔助資源的部署和刪除,如果賬號(hào)為子賬號(hào),需要為該子賬號(hào)添加指定的一些權(quán)限,具體權(quán)限集合可參考:
https://github.com/devsapp/fc/blob/main/docs/zh/command/proxied.md#%E6%9D%83%E9%99%90%E4%B8%8E%E7%AD%96%E7%95%A5%E8%AF%B4%E6%98%8E
「02」
參數(shù)引入
完成以上前置條件的準(zhǔn)備后,我們先了解一下調(diào)試指令中與斷點(diǎn)調(diào)試所相關(guān)的具體參數(shù)
(可滑動(dòng)):
-c, --config [vscode/pycharm/intellij] [Required] Select which IDE to use whendebugging and output related debugconfig tips for the IDE. value:vscode/pycharm/intellij-d, --debug-port number [Required] Specify the local functioncontainer starting in debug mode, andexposing this port on localhost--debug-args string [Optional] Additional parameters thatwill be passed to the debugger--debugger-path string [Optional] The path of the debugger onthe host--tmp-dir string [Optional] The temp directory mounted to'/tmp' , default:'./.s/tmp/invoke/serviceName/functionName/'
使用斷點(diǎn)調(diào)試時(shí),--config 參數(shù)以及 --debug-port 參數(shù)是必要的:
--config 會(huì)指定斷點(diǎn)調(diào)試的 IDE 環(huán)境,目前支持 VSCode、Pycharm 、Intellij 三種。
--debug-port 會(huì)指定調(diào)試的監(jiān)聽(tīng)端口。
另外,其余三種參數(shù)是可選的:
--debug-args 會(huì)自定義程序啟動(dòng)時(shí)的調(diào)試參數(shù),不指定時(shí)默認(rèn)的調(diào)試參數(shù)可以參考文末附錄部分。
--debugger-path 會(huì)將本地指定路徑掛載到程序運(yùn)行環(huán)境的 /tmp/debugger_file?之中。
--tmp-dir 會(huì)將本地指定路徑掛載到程序運(yùn)行環(huán)境中的 /tmp 目錄上,在調(diào)試時(shí),程序?qū)懭?/tmp 的結(jié)果文件則會(huì)在映射到本地目錄,用于驗(yàn)證結(jié)果是否符合預(yù)期。
「03」
實(shí)操演練
1)VSCode
- 調(diào)試 Event 函數(shù):
# 本地調(diào)試$ s local invoke --config vscode --debug-port 3000# 端云聯(lián)調(diào)$ s proxied setup --config vscode --debug-port 3000
啟動(dòng)指令執(zhí)行后,本地的函數(shù)計(jì)算執(zhí)行環(huán)境會(huì)有一定阻塞,我們需要等待調(diào)用;與此同時(shí)當(dāng)前項(xiàng)目會(huì)生成 .vscode/launch.json 文件,該文件是基于 VSCode 進(jìn)行調(diào)試的配置文件,若該文件已經(jīng)存在,那么啟動(dòng)指令會(huì)打印相應(yīng)配置文本,如下圖所示,需要利用這部分內(nèi)容覆蓋已有 .vscode/launch.json 中的內(nèi)容。
.vscode/launch.json 更新內(nèi)容示例
VSCode 啟動(dòng)調(diào)試器示意圖對(duì)于本地調(diào)試而言,啟動(dòng)調(diào)試器后,程序便已經(jīng)啟動(dòng),此時(shí)就可以開(kāi)始進(jìn)行我們的斷點(diǎn)調(diào)試工作了。如果是端云聯(lián)調(diào)的話,啟動(dòng)調(diào)試器后,在啟動(dòng)指令終端頁(yè)面,會(huì)出現(xiàn) "Debugger attached." 字段,這時(shí)說(shuō)明調(diào)試器也已啟動(dòng)成功,正在等待被調(diào)用,接下來(lái)我們繼續(xù)進(jìn)行如下步驟即可。
調(diào)試 php7.2 Event 函數(shù)
php7.2 runtime 的本地調(diào)試?IDE 建議使用 VSCode,其斷點(diǎn)調(diào)試步驟與其他語(yǔ)言有一定差異性,因此單獨(dú)進(jìn)行介紹。目前 php7.2 runtime 不支持端云聯(lián)調(diào)斷點(diǎn)調(diào)試。
step1:首先啟動(dòng) Serverless 應(yīng)用,打開(kāi)終端,進(jìn)入目標(biāo)項(xiàng)目下,輸入啟動(dòng)指令 s local invoke --config vscode --debug-port 3000。
與之前不同的是,Event 函數(shù)啟動(dòng)指令執(zhí)行完成后,并不會(huì)出現(xiàn)阻塞的情況,而是會(huì)直接執(zhí)行成功,同時(shí)在當(dāng)前項(xiàng)目下會(huì)生成 .vscode/launch.json 文件,如前文所述。
step2:啟動(dòng)斷點(diǎn)調(diào)試器,打開(kāi) VSCode 界面,然后打開(kāi) s.yml 中 codeUri 所存放的源代碼,為其打上斷點(diǎn),接著點(diǎn)擊開(kāi)始調(diào)試按鈕,具體執(zhí)行如下圖所示。

step3:開(kāi)始斷點(diǎn)調(diào)試:打開(kāi)一個(gè)新的終端頁(yè)面,再次輸入啟動(dòng)指令 s local invoke --config vscode --debug-port 3000?后,程序啟動(dòng),斷點(diǎn)調(diào)試開(kāi)始。
- 調(diào)試 Http 函數(shù)
VSCode 啟動(dòng)調(diào)試器示意圖調(diào)試 php7.2 Http 函數(shù)
php7.2 runtime 的本地調(diào)試 IDE 建議使用 VSCode,其斷點(diǎn)調(diào)試步驟與其他語(yǔ)言有一定差異性,因此單獨(dú)進(jìn)行介紹。目前 php7.2 runtime 不支持端云聯(lián)調(diào)斷點(diǎn)調(diào)試。
step1:首先啟動(dòng) Serverless 應(yīng)用,打開(kāi)終端,進(jìn)入目標(biāo)項(xiàng)目下,輸入啟動(dòng)指令 s local start --config vscode --debug-port 3000,啟動(dòng)指令執(zhí)行后,會(huì)在當(dāng)前項(xiàng)目下會(huì)生成 .vscode/launch.json 文件,如前文所述,同時(shí)項(xiàng)目會(huì)阻塞住,此時(shí)需要執(zhí)行 Ctrl+C 退出。
step2:啟動(dòng)斷點(diǎn)調(diào)試器,打開(kāi) VSCode 界面,然后打開(kāi) s.yml 中 codeUri 所存放的源代碼,為其打上斷點(diǎn),接著點(diǎn)擊開(kāi)始調(diào)試按鈕,具體執(zhí)行如下圖所示。

step3:開(kāi)始斷點(diǎn)調(diào)試:打開(kāi)一個(gè)新的終端頁(yè)面,再次輸入啟動(dòng)指令 s local start --config vscode --debug-port 3000 后,本地的函數(shù)計(jì)算執(zhí)行環(huán)境會(huì)阻塞等待調(diào)用,并打印訪問(wèn) http 函數(shù)的 url 字段,可以通過(guò) curl 指令、瀏覽器等方式訪問(wèn) Http 函數(shù)的 URL,此時(shí)程序啟動(dòng),斷點(diǎn)調(diào)試開(kāi)始。
step4:結(jié)束斷點(diǎn)調(diào)試:調(diào)試完成后,主動(dòng)關(guān)閉斷點(diǎn)調(diào)試器,然后在啟動(dòng)指令終端頁(yè)面,執(zhí)行 Ctrl+C 即可退出調(diào)試進(jìn)程。
2)Intellij
基于 Intellij 進(jìn)行斷點(diǎn)調(diào)試時(shí),針對(duì)不同語(yǔ)言需要手動(dòng)在 IDE 中配置相應(yīng)地?cái)帱c(diǎn)調(diào)試器,由于使用 Intellij 開(kāi)發(fā)最多的語(yǔ)言是 Java,同時(shí)更換 IDE 后,唯一不同的步驟只有“啟動(dòng)斷點(diǎn)調(diào)試器”,因此接下來(lái)我們將以本地調(diào)試 Java Event 函數(shù)為例,對(duì)“啟動(dòng)斷點(diǎn)調(diào)試器”步驟進(jìn)行詳細(xì)說(shuō)明。
step1:啟動(dòng) Serverless 應(yīng)用:由于 Java 是編譯型語(yǔ)言,因此在開(kāi)始前需要對(duì)程序進(jìn)行打包,本文示例會(huì)使用 mvn package 對(duì)函數(shù)打包,然后執(zhí)行啟動(dòng)指令 s local invoke --config intellij --debug-port 3000。
step2:啟動(dòng)斷點(diǎn)調(diào)試器:
打開(kāi) Intellij 界面,在菜單欄依次選擇 Run -> Edit Configurations。
隨后如下圖所示,新建一個(gè) Remote JVM Debug。
新建 Remote JVM Debug接著,自定義調(diào)試器名稱(chēng),并將端口設(shè)置為 3000,如下圖所示。
Intellij 調(diào)試器配置最后,打開(kāi) s.yml 中 codeUri 存放的源代碼,為其打上斷點(diǎn),接著點(diǎn)擊開(kāi)始調(diào)試按鈕,如圖所示。
Intellij 啟動(dòng)斷點(diǎn)調(diào)試器3)Pycharm
當(dāng)前只有本地調(diào)試能夠在 Pycharm 中進(jìn)行斷點(diǎn)調(diào)試操作,支持的運(yùn)行時(shí)有 python2.7 和 python3兩個(gè)版本。在 Pycharm 中進(jìn)行斷點(diǎn)調(diào)試時(shí),不僅需要在 IDE 中配置斷點(diǎn)調(diào)試器,還需要對(duì)使用者的源碼進(jìn)行侵入式修改,由于操作步驟內(nèi)容與常規(guī)內(nèi)容有所不同,接下來(lái)我們?cè)斀庖幌逻@部分的調(diào)試步驟。
step1:啟動(dòng) Serverless 應(yīng)用:首先,打開(kāi)終端,進(jìn)入目標(biāo)項(xiàng)目下,輸入啟動(dòng)指令:
# event 函數(shù)$ s local invoke --config pycharm --debug-port 3000# http 函數(shù)$ s local start --config pycharm --debug-port 3000
與之前不同的是,Event 函數(shù)啟動(dòng)指令執(zhí)行完成后,并不會(huì)出現(xiàn)阻塞的情況,而是會(huì)直接執(zhí)行成功。此時(shí)就需要記錄 "Tips for PyCharm remote debug" 內(nèi)容,具體內(nèi)容示例如圖所示,記錄完成后,如果是 Http 函數(shù),則輸入 Ctrl+C 退出啟動(dòng)程序。
Tips for PyCharm remote debug 內(nèi)容示例step2:接下來(lái)啟動(dòng)斷點(diǎn)調(diào)試器:?jiǎn)?dòng)斷點(diǎn)調(diào)試器主要包含 IDE 斷點(diǎn)調(diào)試器配置和源碼更新兩部分。
新建 Python Debug Server隨后設(shè)置自定義調(diào)試器名稱(chēng),并基于圖五中獲取的內(nèi)容配置 IDE host name、Port 以及 Path mappings 這三個(gè)調(diào)試器配置的詳情,如圖中所示。
pycharm 調(diào)試器配置隨后打開(kāi) s.yml 中 codeUri 存放的源代碼,將例圖中(Tips for PyCharm remote debug 內(nèi)容示例)的代碼內(nèi)容粘貼到代碼開(kāi)頭,然后按需在源碼指定位置打上斷點(diǎn),接著點(diǎn)擊開(kāi)始調(diào)試按鈕,具體操作如圖 (pycharm 啟動(dòng)斷點(diǎn)調(diào)試器)所示。
Tips for PyCharm remote debug 內(nèi)容示例
pycharm 啟動(dòng)斷點(diǎn)調(diào)試器step3:開(kāi)始斷點(diǎn)調(diào)試:打開(kāi)終端,并進(jìn)入目標(biāo)項(xiàng)目,執(zhí)行啟動(dòng)指令,p.S.此時(shí)可以不用帶上斷點(diǎn)調(diào)試的相關(guān)參數(shù)。
# event 函數(shù)$ s local invoke# http 函數(shù)$ s local start
Event 函數(shù)啟動(dòng)指令執(zhí)行后會(huì)直接進(jìn)入斷點(diǎn)調(diào)試階段;Http 函數(shù)啟動(dòng)指令執(zhí)行后,可以先通過(guò) curl 指令、瀏覽器等方式訪問(wèn) Http 函數(shù)的 URL,此時(shí)程序會(huì)啟動(dòng),斷點(diǎn)調(diào)試就開(kāi)始了。
step4:結(jié)束斷點(diǎn)調(diào)試:調(diào)試完成后,主動(dòng)關(guān)閉斷點(diǎn)調(diào)試器,對(duì)于 Http 函數(shù)而言,在啟動(dòng)指令終端頁(yè)面,需執(zhí)行?Ctrl+C?方可退出調(diào)試進(jìn)程。
結(jié)語(yǔ)
Serverless 應(yīng)用的調(diào)試雖然備受詬病,但是各個(gè)云廠商并沒(méi)有因此放棄在調(diào)試方向的不斷深入探索。以阿里云函數(shù)計(jì)算為例,目前支持提供在線調(diào)試、本地調(diào)試、端云聯(lián)調(diào)等多種調(diào)試方案。而 Serverless Devs 工具所提供的應(yīng)用調(diào)試能力也十分全面了。
上文是我所分享的一些實(shí)操經(jīng)驗(yàn),但是在過(guò)程中也發(fā)現(xiàn)了一些待改進(jìn)的點(diǎn),如:
斷點(diǎn)調(diào)試步驟繁瑣,需要在多個(gè)頁(yè)面來(lái)回切換,如果能將工具集成到 IDE,以插件化形態(tài)供所用戶(hù)使用,簡(jiǎn)化流程,那么體驗(yàn)感會(huì)大幅提升。
斷點(diǎn)調(diào)試模式下的熱更能力:Http 函數(shù)的斷點(diǎn)調(diào)試過(guò)程中,并不支持代碼熱更新,每次修改完代碼后,都需要重新執(zhí)行一遍斷點(diǎn)調(diào)試流程,體驗(yàn)不太流暢。
斷點(diǎn)調(diào)試能力目前還未全面覆蓋所有 Runtime,例如 custom runtime 不支持?jǐn)帱c(diǎn)調(diào)試,php runtime 不支持端云聯(lián)調(diào)斷點(diǎn)調(diào)試等。
希望本文對(duì)你有些幫助。同時(shí)也歡迎大家釘釘掃碼加入 Serverless 開(kāi)發(fā)者技術(shù)群,一起學(xué)習(xí)交流。
Serverless 開(kāi)發(fā)者技術(shù)學(xué)習(xí)群
附錄
「01」
默認(rèn)調(diào)試參數(shù)

「02」
斷點(diǎn)調(diào)試實(shí)操視頻
下面的動(dòng)圖教程均已提前完成文中提到的 “前置操作” 步驟,若要參考具體動(dòng)圖進(jìn)行實(shí)踐,請(qǐng)先完成上文 “前置操作” 的相關(guān)流程。
1)VSCode
本地調(diào)試 Event 函數(shù)
本地調(diào)試 php7.2 event 函數(shù)
端云聯(lián)調(diào) Event 函數(shù)
本地調(diào)試 Http 函數(shù)
本地調(diào)試 php7.2 Http 函數(shù)
端云聯(lián)調(diào) Http 函數(shù)
2)Intellij
本地調(diào)試 Event 函數(shù)
端云聯(lián)調(diào) Event 函數(shù)
3)Pycharm
本地調(diào)試 Event 函數(shù)
本地調(diào)試 Http 函數(shù)
社區(qū)網(wǎng)址一覽(可滑動(dòng)):
社區(qū)官網(wǎng):http://www.serverless-devs.com/ServerlessDesktop桌面客戶(hù)端:https://serverlessdevs.resume.net.cn/zh-cn/desktop/index.htmlServerless應(yīng)用開(kāi)發(fā)者套件:http://serverless-dk.oss.devsapp.net/docs/tutorial-dk/intro/reactServerless?Devs?CLI:https://serverlessdevs.resume.net.cn/zh-cn/cli/index.htmlServerless?Hub應(yīng)用中心:https://serverlesshub.resume.net.cn/#/hubs/special-view
RECRUITMENT
極速上手?Serverless
隨著 Serverless 熱度不斷升高,越來(lái)越多人期望在實(shí)際工作中能快速上手。為了讓更多 Serverless 初學(xué)者真正學(xué)會(huì) Serverless 理論知識(shí),在工作中根據(jù)需要靈活應(yīng)用 Serverless 技術(shù),阿里云 Serverless 團(tuán)隊(duì)推出技術(shù)圖譜,本課程包含機(jī)頻、動(dòng)手實(shí)驗(yàn)、電子書(shū)、直播、開(kāi)源項(xiàng)目多種形式內(nèi)容,讓各位開(kāi)發(fā)者即學(xué)即用,跑步入場(chǎng)享受 Serverless 技術(shù)紅利!

戳點(diǎn)擊閱讀原文,了解函數(shù)計(jì)算相關(guān)資訊!