2012-01-22 60 views
4

我想用某種服務服務器處理來自javascript客戶端的大量(> 100k/sec)POST請求。這些數據並不會存儲很多,但我必須處理所有這些數據,因此我無法將整個服務器的功耗用於僅處理請求。所有的處理都需要在同一個服務器實例中完成,否則我將需要使用數據庫進行服務器之間的同步,這將會在數量級上變慢。如果我不需要發回任何數據,那麼服務器是否可以處理更多請求?

但是,我不需要將任何數據發送回客戶端,他們甚至不期望他們。 到目前爲止,我的計劃是創建幾個代理服務器實例,這些代理服務器實例將能夠緩衝請求並將它們發送到更大包中的主服務器。

例如,假設我需要處理200k個請求/秒,每個服務器可以處理40k個請求。我可以分解他們中的5個。然後每個緩衝請求將其發送回主服務器,數量爲100包。這將導致主服務器上的每秒2k個請求(但是,每個消息將會大100倍 - 這可能意味着大約100-200kB) 。我甚至可以使用UDP將它們發送回服務器以減少所需資源的數量(然後我只需要在主服務器上使用一個套接字,對吧?)。

我只是想,如果沒有其他的方式來加快事情。特別是,當我說我不需要發回任何東西時。我也完全控制javascript客戶端,但不幸的JavaScript無法使用UDP發送數據,這可能是我的解決方案(我甚至不關心是否會丟失0.1%的數據)。

任何想法?


編輯迴應給我的答案到目前爲止。

問題不在於服務器在處理隊列中的事件或將事件放入隊列本身時變慢。事實上,我打算使用干擾模式(http://code.google.com/p/disruptor/),經證實,該模式每秒可處理多達600萬個請求。

我可能會遇到的唯一問題是需要同時打開100,200或300k套接字,這是任何主流服務器無法處理的。我知道一些定製的解決方案是可能的(http://www.metabrew.com/article/a-million-user-comet-application-with-mochiweb-part-3),但我想知道是否沒有辦法更好地利用事實,我不必重播客戶端。

(例如某種方式嵌入在最初的TCP數據包中的部分數據和處理TCP數據包,他們將UDP或者其他類型的魔法;))

回答

1

做一個獨特的和快速的(可能在C)函數從一個非常快速的服務器(如nginx)獲取所有請求。這個函數的唯一工作就是將請求存儲在一個非常快的隊列中(比如redis,如果你有足夠的內存)。

在另一個進程(或服務器)中,停止隊列並執行真正的工作,逐個處理請求。

1

如您所說,如果您擁有客戶端的控制權,那麼您的代理服務器甚至不需要是HTTP服務器,因爲您可以認爲所有請求都是有效的。

您可以將其實現爲一個非HTTP服務器,該服務器僅發回200,讀取客戶端請求,直到它斷開連接,然後將請求排隊等待處理。

0

我想你所描述的是一個Message Queue的實現。你也需要把這些請求交給你使用的任何隊列(RabbitMQ相當不錯,有很多選擇)。

你還需要其他的東西在運行,它可以做你想要的任何處理請求。你沒有說得很清楚,所以我不太確定什麼適合你。本質上,這個想法將是傳入的請求儘可能快地被您的Web服務器儘可能快地轉儲到隊列中,然後Web服務器可以自由地回到提供更多的請求。當系統有一些資源時,它使用它們來處理隊列,但是當它很忙時,隊列就會不斷增長。

不知道你在使用什麼平臺,但可能想看看類似Lighttpd這樣的服務POSTs。你可能會(如果同域限制不會讓你失望),讓Lighttpd在你的應用程序的子域上運行(so post.myapp.com)。如果沒有,你可以在你的網絡服務器之前放置一個合適的負載平衡器(因此所有請求都轉到www.myapp.com,負載平衡器決定是否將它們轉發到Web服務器或隊列處理器)。

希望幫助

0

考慮使用MongoDB的堅持爲您的要求,這是射後不理機制可以幫助您的服務器響應速度更快。

相關問題