2011-06-18 161 views
2

我在1.2中發現了a question that explains how Play Framework's await() mechanism works。本質上,如果您需要做一些將會阻塞一段時間的事情(例如,緩慢的外部http請求),您可以暫停您的請求,並釋放該工作人員在阻塞時處理其他請求。我猜測,一旦你的阻止操作完成,你的請求被重新安排進行繼續處理。這不同於在後臺處理器上安排工作,然後讓瀏覽器輪詢完成,我想阻止瀏覽器而不是工作進程。推遲攔截Rails請求

不管我對遊戲的假設是否是真信,有沒有在Rails應用程序這樣的技術?我想可以考慮這是一種長時間輪詢,但除了「使用節點」之外,我沒有找到關於該主題的許多建議。

回答

3

我對長期的請求,阻止工人採取其他請求了類似的問題。這是所有Web應用程序的問題。即使Node.js可能無法解決在工作人員上花費太多時間的問題,或者可能會耗盡內存。

Web應用程序我對工作有發送請求到Rails的REST API網絡接口,那麼Rails的控制器有權要求運行繁重耗時的任務,得到一些數據備份節點REST API。從Rails到Node.js的請求可能需要2-3分鐘。

我們仍在試圖找到不同的方法,但也許以下可以爲你工作,或者你能適應的一些想法,我很想得到一些反饋太:

  1. 前端做出的請求Rails API在同一會話中生成標識符[A]。 (該標識符有助於識別來自同一用戶會話的先前請求)。
  2. 滑軌API代理前端請求和標識符[A]到Node.js的服務
  3. Node.js的服務此作業添加到隊列系統(例如RabbitMQ的,或Redis的),該消息包含識別符[一個]。 (這裏你應該根據自己的情況考慮,同時假設系統將消耗隊列作業並保存結果)

  4. 如果同一個請求再次發送,根據需要,可以殺死當前作業使用相同的標識符[A]並安排/排列最新請求,或忽略等待第一個請求完成的最新請求,或者其他決策符合您的業務需求。

  5. 前端可以發送間隔REST請求,以檢查是否有識別符[A]的數據處理已完成或沒有,那麼這些要求是重量輕,速度快。

  6. 一旦Node.js的完成作業,您可以使用郵件訂閱系統或等待下一次的到來檢查狀態請求,並將結果返回到前端。

您還可以使用負載平衡器,例如,亞馬遜負載平衡器,Haproxy。 37signals有一個blog post and video關於使用Haproxy卸載一些長時間運行的請求,不會阻止較短的請求。

Github上使用類似的策略來處理長期請求生成提交/貢獻可視化。他們還設定了拉動時間的限制。如果時間太長,Github會顯示一條消息,說它太長了,它已被取消。

YouTube對於排隊較長的任務有一個很好的信息:「這需要比預期更長的時間,您的視頻已排隊並將儘快處理。」

我認爲這只是一個解決方案。您還可以看看EventMachine gem,它有助於提高性能,處理程序並行或異步請求。

由於這類問題可能涉及一個或多個服務。考慮提高這些服務(例如數據庫,網絡,消息協議等)之間性能的可能性,如果緩存可能有幫助,嘗試緩存頻繁的請求或預先計算結果。