2011-09-29 74 views
1

我有一個數組填充了潛在的大量記錄。每個記錄應由服務器保存在RESTful RecordsController中。我在當下的解決方案是這樣的:RESTful Rails控制器ans net/http作爲客戶端 - 很多請求很慢

def self.send! options = nil 
    records = fetch_records 
    records.each do |r| 
    send_data!(r) ? records = records.delete_if{|rec| rec == r } : break 
    end 
    storage.save! records 

    true 
end 

private 

def self.send_data! record, options = nil 
    begin 
    response = Net::HTTP.Proxy(configuration.proxy_host, configuration.proxy_port).start(configuration.host, configuration.port) do |http| 
     request = Net::HTTP::Post.new(request_path options) 
     request.body = record.to_json 
     http.request request 
    end 
    raise StandardError unless response.code == "200" 
    rescue Exception => e 
    return false 
    end 

    true 
end 

該解決方案的好處是,如果一個ConnectionError,ConnectionTimeout或SERVERERROR發生時,未發送的記錄,獲得本地存儲和以後可以再次提交。匹配的控制器是標準的Rails控制器。

我現在的問題是,在生產模式下,這似乎很慢。大約有4個請求/秒,服務器不是瓶頸。

現在的問題是,它可以幫助實例化HTTP客戶端一次,並使用相同的連接發送所有記錄。我沒有找到解決方案來實現這一點,因爲我需要在這裏代碼的save_or_store行爲。

另一個解決方案可能不是將記錄依次傳輸,而是將它們分組並創建一個新的控制器,該控制器接受我的記錄組來存儲它們。

所以這個問題歸結爲比技術更具建築性的問題。無論哪種方式,我想知道是否可以保持HTTP連接打開並以這種方式加快我的解決方案。

任何想法?

問候 菲利克斯

回答

0

如果我讀發送!方法正確,你循環每個記錄,並在該循環內剛剛從數組中刪除當前記錄和發送一切?爲了節省計算方面的工作量,請使用Array類的delete()方法而不是delete_if。

def self.send! options = nil 
    records = fetch_records 
    records.each do |r| 
    if send_data!(r) 
     records.delete(r) 
    else 
     break 
    end 
    end 
    storage.save! records 

    true 
end 

雖然我不知道你在哪裏傳遞send_data的記錄參數!方法。因爲terinary會使用該方法的結果。

網絡http可能需要一些時間才能運行所有請求。我知道當我運行幾百個URL來檢查響應代碼時,它會在5-10分鐘內完成。我自己並沒有太多用處,但請看看:https://github.com/jnunemaker/httparty。也許它會對你更好。

+0

嘿agmcleod,thx爲您的建議。 httparty是一個咕h提示,我會看看它。上面的示例代碼簡單地錯過了send_data的參數! ...修正了這一點。 – GeorgieF

+0

酷,更新我的答案以反映這一點。 – agmcleod

2

切換到em-http-request - 基於EventMachine的HTTP客戶端 - 並使用其Multi接口同時發送多個請求可能會提高吞吐量。

但是更好的HTTP客戶端的好處可以忽略不計。由於您不會對從控制器獲得的HTTP響應執行任何操作,這意味着您不使用HTTP作爲應用程序協議,所以您的問題的最佳解決方案是實際發送整個陣列以在服務器端進行處理。畢竟,你不必爲每一條記錄提出單一請求的代價。最終,如果你願意的話,最好公開一個沒有處理的記錄列表,這樣你就可以重新提交或者只是忽略它。

我想把MessagePack混合在一起,以串行化數組並減小有效負載的大小並加快消息交換。

+1

em-http-request是一個很好的提示。事實上,我的問題是數據聚合,如果我的記錄...這一直很慢。解決了這個問題,並創建了一個接受批量記錄的控制器,使其更快。 em-http-request將成爲下一個任務之一。這個提示很多。 – GeorgieF