開發函數計算的正確姿式 —— 排查超時問題

寫不盡的 code,查不完的 bug
一般咱們寫 bug,哦,不對,寫代碼時總不會一路順風,每每各類 bug 充斥其中,即便測試有較高的代碼覆蓋率每每也會有漏網之魚。能寫出一些比較隱蔽或者看起來像 feature 的 bug,而且通過了測試、code review 等層層的考驗,最終 merge 到主幹,這也算的上是一種本事。node

此次,咱們討論的場景是,當你製造的 bug 被別人發現或者不當心把本身坑了,而不得不去 fix,且你本身也忘了這個 bug 是怎麼寫的了,在這種狀況下,如何排查問題?json

一鼓作氣,bug 側漏
var request = require('request');api

exports.handler = function(event, context, callback) {函數

console.log("event: " + event);
console.log('context: ', JSON.stringify(context));

const options = {
    url: 'https://saweather.market.alicloudapi.com/spot-to-weather?area=%E6%B3%B0%E5%B1%B1&need3HourForcast=0&needAlarm=0&needHourData=0&needIndex=0&needMoreDay=0',

    headers: {
        Authorization: 'APPCODE 5d9129e294fc4f518793ae9f9a15dbff'
    }
}

request(options, function (error, response, body) {
    if (error || response.statusCode != 200) {
        console.log("error " + error);
        return 
    } 

    console.log(body.day_weether);
});

};
很簡單的一個 nodejs 函數,剛剛接觸函數計算每每會意氣風發的一口氣抒寫出這樣一段代碼,一般是爲了簡單測試一下函數的使用流程。可是發佈到上去後,卻出現了調用超時的問題。工具

大膽猜想,當心求證
首先,在無從下手的狀況下,你大膽猜想以下:學習

函數入口寫錯了
代碼中的邏輯有問題
函數計算服務有問題
爲了排除其中的 3 選項,首先經過 fun local,在本地運行測試:測試

fun local invoke nodejs_timeout
獲得結果:ui

圖片描述

能夠看到,程序也被卡在這裏了。由此,能夠排除掉 3 的可能性。url

接着,能夠經過加一些日誌,或者單步調試來進一步縮小排查的範圍,這裏選用單步調試,由於這種方法每每更簡單。spa

首先,利用 VSCode 在側邊欄下一個斷點:

圖片描述

而後使用如下命令將函數以調試的方式運行起來(調試基本用法 參考,這裏再也不過多闡述):

fun local invoke -d 3000 nodejs_timeout
而後單擊 VSCode 的開始調試按鈕進行調試:

圖片描述

能夠看到,函數被正確的調用了,且進入到了入口函數。到此爲止,能夠排除掉 1 的可能性。

接下來,就要確認 2 可能性中存在的問題。

在 request 處的代碼設置斷點,continue 到裏面,而後在 Local 能夠看到運行到此處時的變量的值。

圖片描述

能夠看到,http 請求返回的 resposne 的 statusCode 爲 200,符合預期。body 也是有數據的,這個也符合預期。

把 body.weakday 放到 watch 裏面執行一下,看下結果。

圖片描述

這個就不是預期中的值了。

仔細看下 body 這個對象,發現其顯示格式不對,經過 typeof 將 body 的類型打印出來:

圖片描述

這貨居然是個 string!

剛想破口大罵,但一想這代碼是本身寫的,趕忙閉嘴。

那就轉成 json 吧。

但轉完後,發現事情更不對了,day_weether 並不直接在 body 下,而是隱藏的很深。

圖片描述

並且名字不叫 day_weether,這裏有個拼寫錯誤。正確的寫法應該是:

JSON.parse(body).showapi_res_body.f1.day_weather
What the.... 髒話都到嘴邊了,但一想代碼本身寫的,總不能罵本身吧,趕忙修吧。

把正確的表達式貼到 Watch 裏面,查看,果真可以取到正確的值:

驗證完畢後,將正確的值粘貼到代碼中,心想,總算解決了。

從新運行一下函數,發現果真可以取到數據了:

但函數依舊卡在這裏,並無繼續往下走————超時的問題依舊存在!

如今,憤怒的心情已經沒有了,取而代之的是藍瘦,香菇。站起身,望望窗外,讓冷風肆虐你的臉龐。許久,內心平靜一些了。

山窮水盡,柳暗花明
冷靜下來,理一理線索:

從剛纔的調試結果來看,函數已經運行,且得到了正確的結果,可是函數卻沒有結束,直到超時。忽然,一個隱約的答案在你身邊徘徊,你拼命想要抓住,來回踱步,驀地,像是出現了救命稻草通常,打開了函數計算 Nodejs 的 文檔,你用盡力氣擺動眼球,快速閱讀文檔,並在內心懇求那根救命稻草的出現。恍然間,你如同穿越了一道厚重的鐵門,身邊的光線忽然由暗變亮,你被這明亮的光線刺的睜不開眼睛。但你知道,答案就在這刺眼的光芒裏。眼淚,沒能止住,順着你的臉龐緩慢地流了下來。終於,你鬆開了緊握的拳頭,彎下了一直挺直的腰板,眼淚鼻涕忽然傾瀉而出,你————失聲痛哭。全部的委屈從心裏通過喉嚨、鼻子、眼睛發泄出來,伴隨着這一陣陣漸漸衰弱的迴盪聲,遠去。

哭罷,擦乾眼淚,平復下本身的心情,將那一段你追尋許久的答案緩慢但卻有力的敲擊出來:

callback(null, JSON.parse(body).showapi_res_body.f1.day_weather);
終於,這段代碼就如同你家叛逆的孩子,脫去叛逆的假裝,顯現出它乖巧的樣子:

欲善其事,先利其器
通過這一次事件,你總結出三條經驗:

寫代碼要耐心、細心,每一段代碼都要通過思考。一口氣將功能寫完,每每是看上去寫的快,但實際上會埋不少坑,坑到別人還好,每每不當心會把本身坑了。
要多讀文檔。使用語言,要讀語言文檔,使用第三方庫,要讀庫的文檔,使用產品,要讀產品文檔。若是不仔細閱讀僅憑本身的猜想去寫,寫出的代碼每每漏洞百出。男人千萬不要硬撐,別對本身這麼很。累了要休息,能夠讀讀文檔放鬆下。俗話說得好,磨刀不誤砍柴工!
Fun 工具的熟練使用重中之重。 在前兩點都沒作到的狀況下,卻能最終將問題排查出來,Fun 工具功不可沒!但與之功勞成反比的是,對 Fun 工具的學習尤爲是本地調試功能,花的時間反而是最少的,如此巨大的收益比,使本身下定決心,必定要再花些時間,把 Fun 工具 吃透!
總結完,你又用心的看着本身寫下的代碼,就如同看向本身的孩子,寵溺、疼愛、氣憤各類心情夾雜在一塊兒。忽然,你一皺眉,呵斥道:這樣不對,異常的時候,也要返回!

因而,你糾正了代碼的錯誤行爲:

if (error || response.statusCode != 200) {

console.log("error " + error);
callback(error, null) ;

} 就如同,訓斥完與人打架的孩子,看到孩子聽話了,你露出了欣慰的微笑。

相關文章
相關標籤/搜索