2013-12-16 102 views
4

有沒有辦法在rails中爲POST命令維護/使用持久連接?使用POST的持久/保持HTTP連接在Rails中

我想創建一個API,其中我的應用程序接受來自外部服務的數據流的數據流(我在寫這個外部服務,所以我可以在這裏靈活地設計我的設計)。速度至關重要。我需要以每秒1000+點的速度從外部來源獲取信息。在與一些計算機科學家交談時,人們提出了使用持久連接的想法,以便只需要執行一次昂貴的TCP握手。使用外部服務中的庫,然後創建多個POST項目,這些項目被推送到我的Rails應用程序中,然後逐個處理這些POST項目。

我對rails範例的理解是每個請求(POST,GET,PUT等)都需要一個TCP連接。有沒有一種方法可以利用一個TCP連接來獲取多個POST?

我目前使用下列內容:

  • 的Rails 3.2
  • 的Ruby 1.9.3(必要切換到2.0)

編輯

爲了幫助澄清我的目標是什麼:

我有一個外部系統,每秒收集1,000個數據點(3個浮點數,時間戳和2個整數)。我想將這些數據推送到我的Ruby on Rails服務器上。我希望有一個正確配置的系統,我可以實時使用HTTP堆棧(當數據點被收集後,我將它推送到我的rails服務器)。我也可以減慢傳輸速率,並將數據分組在一起發送。我研究過使用消息隊列,但是我想看看在去專門的隊列API之前是否可以編寫更「標準的」HTTP API。

+0

知道你通過'POST'發送什麼是很有意思的。如果可以將它安裝到多部分MIME消息中,則可以傳輸請求,進一步減少開銷。 – DaSourcerer

+0

@DaSourcerer我更新了我的問題,希望能夠讓你瞭解我正在努力完成的任務。我從來沒有聽說過「流式傳輸」一個請求。我可以通過谷歌瞭解這一點? –

+0

謝謝。我必須說,這是一個非常有趣的問題。我有一些想法可以幫助你。隨着時間的推移,我會更新我的答案。 – DaSourcerer

回答

5

認爲Net::HTTP::Persistent圖書館是你在找什麼。還有this圖書館通過持續連接實現連接池還有一步。但是,因爲聽起來你只有一個API點,這可能是矯枉過正的。

一些額外的想法:如果你真的看到原始速度,可能需要發送一個多部分POST請求來進一步減少開銷。這將歸結爲執行reverse server push

爲此,您的rails應用程序需要接受chunk-encoded請求。這一點非常重要,因爲我們不斷地將數據流式傳輸到服務器,而不知道最終的消息體最終會持續多久。 HTTP/1.1要求所有消息(即響應請求)要麼是塊編碼的,要麼是由Content-Length標頭(參見RFC 2616, section 4.4)指定的主體大小。然而,大多數客戶更喜歡後者選項,這導致一些網絡服務器不能很好地處理塊編碼的請求(例如nginx在v1.3.9之前沒有實現這個)。

作爲一種序列化格式,我可以安全地推薦JSON,它非常快速生成並被廣泛接受。 RoR的實現可以在here找到。你可能想看看this的實現,以及它本身是在使用流,因此可能更適合。如果您發現JSON不適合您的需求,請嘗試使用MessagePack

如果達到網絡飽和度,可能需要調查request compression的可能性。

一切放在一起,你的要求可能是這樣的(壓縮和塊編碼剝離的可讀性的緣故):

POST /api/endpoint HTTP/1.1 
Host: example.com 
Content-Type: multipart/mixed; boundary="---boundary-" 
Transfer-Encoding: chunked 
Content-Encoding: deflate 

---boundary- 
Content-Type: application/json 

{...} 
---boundary- 
Content-Type: application/json 

{...} 
---boundary--- 

MIME類型爲multipart/mixed,因爲我覺得這是最恰當的。它實際上意味着消息部分是不同的內容類型。但據我所知,這是無處執行的,所以multipart/mixed在這裏使用是安全的。 deflate被選爲gzip作爲壓縮方法,因爲它不需要生成CRC32校驗和。這可以提高速度(並節省幾個字節)。

+0

感謝您的詳細回覆。我不熟悉HTTP協議棧。它是請求持久(分塊)連接的客戶端,還是我需要在服務器上進行一些配置? –

+0

這是客戶端請求它,它是需要支持它的服務器。很抱歉,我在農村地區並沒有穩定的聯繫。 – DaSourcerer

+0

你知道配置是否只是在網絡服務器(我使用nginx)還是有一些設置,我需要在Rails中檢查?感謝所有幫助,順便說一句。它非常有用。 –

0

我知道你想要一個HTTP解決方案,但老實說,如果速度很關鍵,我會把HTTP拿出來。 Web套接字似乎更好地適應這個問題。

請參閱從Heroku的一個示例應用程序:https://devcenter.heroku.com/articles/ruby-websockets

而在一般看到Twitter的流API的一個靈感:https://dev.twitter.com/docs/streaming-apis

最重要的是,你可以傳遞的,而不是文本的二進制數據,加快轉移進一步,然後有工作人員攝取和保存數據。

只是我的2分

+0

我想我正在尋找像Twitter的流媒體API,但不是通過HTTP處理? –

+0

實際上是的,但持續連接必須由誰啓動它進行配置。因此,如果您希望其他人打開連接以將數據注入服務器,則必須建立持久連接。使用套接字,您只需要擔心處理數據。 – aledalgrande

+0

我想我接近了解你在暗示什麼。糾正我,如果我錯了:我會創建一個人們將連接到WebSocket啓用服務。然後他們會將信息推送到這個WebSocket服務,並且這個WebSocket服務會將信息推送到我的後端? –