2016-07-07 64 views
0

我目前正在開發一個帶有REST API的節點js應用程序,該應用程序公開了mongo數據庫的數據。NodeJs應用程序 - 重複的作業 - 單個或多個子進程?

應用程序需要通過調用外部服務(可能需要超過一分鐘才能獲取新數據)每5分鐘更新一些數據。

我決定把這個任務隔離到一個child_process但我不知道我應該怎麼需要把這個子進程:

  • 只有函數來執行。時間表由主進程管理。
  • 具有一個獨立的進程,每5分鐘自動刷新一次數據,並在每次刷新完成時向主進程發送消息。

我真的不知道,如果有啓動一個新的子進程,每5分鐘一個大的成本,或者我應該只使用一個長時間運行的子進程,或者如果我在得太多問題^^

編輯 - Inforamtion更新任務

更新任務可能需要長達一分鐘之內,但它是由許多小任務(收集來自許多外部供應商的信息),比異步運行做很多我也不需要一個孩子的過程?

謝謝!

回答

1

只要您使用異步請求,從外部服務獲取數據所需的總時鐘時間無關緊要。重要的是你在這個過程中使用了多少CPU。如果大部分時間都在等待外部服務響應或發送數據,那麼您的node.js服務器在大部分時間都處於空閒狀態,您可能不需要子進程。

因爲node.js是異步的,所以它可以愉快地擁有許多處於「正在運行」的等待響應並且只需很少系統資源的開放請求。

由於node.js是單線程的,因此CPU使用率通常會導致需要子進程。如果從外部服務獲取響應需要5分鐘,但實際CPU時間只有50ms來處理該請求並對其執行操作,則可能不需要子進程。

如果是我,我會將用於與外部服務進行通信的代碼分離到它自己的模塊中,但是我不會添加子進程的複雜性,除非您實際上有一些數據表明這樣的更改是需要。


我真的不知道是否存在開始一個新的子 過程中每5分鐘一個大的成本,如果我只用一個很長一段時間運行 子進程,或者如果我在得太多問題

啓動新的子進程肯定會有一些成本。這並不是很大,但是如果你每5分鐘就要做一次,並且它不佔用大量內存,那麼最好只啓動一次子進程,讓它管理與外部服務完全依賴於它自己,然後它可以根據需要將結果傳回給其他node.js進程。這使得第二個節點進程更獨立,兩個進程之間的唯一交互點就是傳遞更新。功能和責任的分離通常被認爲是一件好事。在一個多開發人員項目中,您可以更輕鬆地讓不同的開發人員在每個應用程序上工作。

+0

好的解釋,所以如果我沒有一些阻塞任務,我不應該擔心之前的問題(=性能問題)發生? – Thomas

+0

@Thomas - 是的,這將是我的建議。除非你有實際證據證明它是必要的,否則不要使事情複雜化。 – jfriend00

1

Node.js有一個能夠處理異步調用的事件驅動架構,因此它不同於典型的C++程序,您將使用多線程/進程架構。

對於您的使用案例,我在想也許您可以利用setInterval重複執行一項操作,您可以使用某種promises框架(如bluebirdJS)定義更多細小的異步調用?

更多信息參見:

的setIntervalhttps://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval

的setInterval()

重複調用功能或執行的代碼段,以固定 時間每次通話之間的延遲。返回一個intervalID。

示例代碼:

setInterval(function() { 
    console.log("I was executed"); 
}, MILLISECONDS_IN_FIVE_MINUTE); 

承諾http://bluebirdjs.com/docs/features.html

示例代碼:

new Promise(function(resolve, reject) { 
    updateExternalService(data) 
    .then(function(response) { 
     return this.parseExtResp(response); 
    }) 
    .then(function(parsedResp) { 
     return this.refreshData(parsedResp); 
    }) 
    .then(function(returnCode) { 
     console.log("yay updated external data source and refreshed"); 
     return resolve(); 
    }) 
    .catch(function(error) { 
     // Handle error 
     console.log("oops something went wrong ->" + error.message); 
     return reject(); 
    }); 
    } 
+0

我已經在使用promise和setInterval,我只是想知道是否需要將任務分離到單獨的進程中?是否有意義 ? – Thomas

+0

你是否僅僅因爲你遇到了一些性能問題而這樣做?嗯,多進程節點體系結構對我來說不太合理。你想利用你所有的CPU核心嗎?可能首先檢查'lscpu'是什麼,如果你意識到你的節點應用程序只使用10個CPU內核中的1個並且程序無法再擴展,那麼可能會嘗試使用多個子節點。否則會更好的做一個代碼分析? –

+0

可能是因爲我暫時沒有任何性能問題,所以我反覆解決了這個問題......所以如果沒有性能問題,也沒有阻塞代碼,我只需要讓事件循環完成這項工作? – Thomas

1

這要看你的應用程序,並自動刷新任務之間的凝聚力。

如果自動刷新任務可以獨立運行,而不與您的應用進行交互,那麼最好將您的任務作爲新進程啓動。直接使用child_process不是一個好主意,spawn/monitor/respawn子進程很棘手,你可以使用crontab或pm2來管理它。

如果自動刷新任務取決於您的應用程序,則可以直接使用child_process,將消息發送給它以進行計劃。但首先嚐試打破這種依賴關係,這將簡化您的應用程序,易於部署和分開維護。子進程長時間運行,或者一個鏡頭不是一個問題,除非在一臺機器上運行數百個這樣的任務。

+0

有趣的,所以也許有一個隊列,讓他們溝通可能是我的解決方案!謝謝 – Thomas

+0

父母和孩子的IPC頻道已經內置:[child.send](https://nodejs.org/api/child_process.html#child_process_child_send_message_sendhandle_options_callback) – tangxinfa

+0

是的,我看到了,但它只適用於你有父/子進程 – Thomas

相關問題