2017-03-21 152 views
5

我使用雲功能的火力地堡到:雲功能的火力地堡性能

  1. 接收來自api.ai
  2. 參數請對第三方API的調用和
  3. 迴應回API .AI。

我對第三方API的調用使用request Node.js module,並且被封裝在index.js中的函數(getInfoFromApi())中。

我遇到的問題是次要函數調用的執行持續時間在15-20秒之間。注意:雲功能本身在400ms範圍內始終執行其執行。

通過向控制檯記錄簡單的註釋我可以看到函數何時啓動,何時調用了輔助函數以及何時從第三方接收到響應,所以我想我可以看到發生了什麼。

粗略地講,時序是這樣的:

  • 0:雲功能初始化
  • 400毫秒:雲計算功能完成
  • 16 S:(!)getInfoFromApi()函數被調用
  • 17號:第三方API返回結果

我的問題:

  • 是否有明顯的原因導致延遲調用輔助功能?這似乎不是由於the cold start issue引起的,因爲雲功能很快就會出現,並且即使在重複呼叫之後延遲也是一致的。
  • 是否使用'請求'節點模塊導致該問題?是否有更好的模塊來創建/管理來自雲功能的http請求?

你可以在這裏看到index.js的簡化要點:https://gist.github.com/anonymous/7e00420cf2623b33b80d88880be04f65

這裏是在例如定時火力地堡控制檯的抓取。注意:輸出與上面的代碼略有不同,因爲我簡化了上面的代碼以幫助理解。 enter image description here

+0

你能分享一下你實際在做什麼的代碼片段嗎? –

+0

@MichaelBleigh我已經整理好了index.js,並將其放在了這裏:https://gist.github.com/anonymous/7e00420cf2623b33b80d88880be04f65/revisions - 這顯然是一個WIP,但希望能告訴你什麼是從API調用.AI。 – James

+0

你可以分享你的程序樣例運行的輸出嗎?您在問題中的時間順序與代碼不匹配(即,在直接調用該函數編寫的代碼發送http響應之前,會打印名爲「** must **」的getInfoFrom3rdParty()似乎與您的時間相矛盾。) –

回答

1

getInfoFrom3rdParty()調用是一個異步事件。但是,您尚未從函數返回承諾,因此函數不會等待異步事件完成。

看起來對我來說,因爲您未返回undefined,函數還會假定它失敗並重試。在重試過程中的某個時刻,異步事件可能在函數退出之前完成(即由於競爭條件而無意的成功)。在其他情況下,我看到了類似的結果,在這些情況下用戶不會在其功能中返回承諾或價值。

我不明白你想做什麼 - 它似乎沒有對第三方結果做任何事情,並且可能不是你的用例的現實主義。但是,這樣的事情可能是你想要什麼:

exports.getInfo = functions.https.onRequest((request, response) => { 
    // .... 

    // NOTE THE RETURN; MOST IMPORTANT PART OF THIS SAMPLE 
    return getInfoFromThirdParty(...).then(() => { 
    response.writeHead(200, {"Content-Type": "application/json"}); 
    response.end(JSON.stringify(payload)); 
    }).catch(e => /* write error to response */); 
}); 

function getInfoFrom3rdParty(food) { 
    reqObj.body = '{"query": "'+food+'"}'; 

    return new Promise((resolve, reject) => { 
     mainRequest(reqObj, function (error, response, body) { 
      // .... 
      if(error) reject(error); 
      else resolve(...); 
      // .... 
     }); 
    }); 
} 
0

我與雲功能體驗,一旦「執行完成」標誌完成,它就會導致延遲(從3秒到15秒)。這會阻止剩餘的執行並增加您的總響應時間。

爲了解決這個問題,您可以嘗試在您的第三方調用中放置Promise,一旦完成,然後執行結束該函數的「response.send()」。

相關問題