2015-04-26 76 views
1

我正在爲簡單的Python多線程Web服務器構建負載生成器。負載生成器使用用戶提供的線程數,啓動客戶端,連接到服務器並請求短文件,然後斷開連接。服務器爲每個新客戶端連接創建一個新線程。提高多線程Web服務器的性能

發生了什麼是我能夠實例化大約100個客戶端線程沒有任何問題。但是當我將它增加到1000或更多的線程時,我得到了不希望的結果。我得到以下錯誤:

  • 錯誤:[錯誤32]破碎管當客戶調用sendall
  • 錯誤:[錯誤54]由對等當客戶調用recv連接重置。

這是怎麼回事,處理這些錯誤的正確方法是什麼?

編輯
很明顯,我可以捕捉到這些套接字錯誤。只是發現上述錯誤,還是應該處理?如果要處理,應該如何處理?這些錯誤不是偶發或隨機發生的;它們會在我的負載生成器產生>〜100個線程時始終如一地發生。

我現在明白了[Errno 32]當套接字的接收端已關閉,然後寫入端嘗試寫入它時,會發生Broken pipe。在這種情況下,接收端(服務器端)提前關閉,但我不知道如何防止這種情況發生,或者甚至有什麼方法。

+2

不確定你,但他們都是相關的客戶端斷開連接,你應該簡單地捕獲這些錯誤作爲例外並關閉連接。 http://stackoverflow.com/questions/180095/how-to-handle-a-broken-pipe-sigpipe-in​​-python – HassenPy

+0

在CPython中,由於使用GIL,使用線程可以提高性能。 (在多線程中運行Python字節碼時,您不會同時使用多個內核。)如果使用'multiprocessing',則可以實際*使用*所有內核。 –

回答

2

這實際上可能反映了簡單多線程的Web服務器的負載限制。

標準Python實現CPython不使用多核心進行多線程,因爲它是global interpreter lock (GIL)。因此,像回答HTTP請求負載這樣的計算綁定任務並不會那麼好。

爲了提高並行性能,您可以:

  • 使用多,像multiprocessing
  • 使用替代Python實現沒有這些線程的限制,像Jython
  • 使用一些替代方法,併發性,例如像Greenlet,事件循環一樣Twisted等微螺紋

生產級Web服務器通常使用這兩個選項,使用多個工作進程每個運行多個線程。

+0

我真的很喜歡的是一個缺乏切換框架或Python實現的解決方案。我覺得我實現套接字的方式不正確。也許確定這些錯誤發生的原因將有助於我改進我的實施。 – cosmosa

+0

@ cosmos1990可能也是如此。只是給了一些指針。 Python *線程化時,您無法迴避這種爭論。) – famousgarkin

+1

測試Web服務器幾乎與cpython中的線程一樣激烈。 :-)目前看來,像nginx這樣的多處理事件驅動設計對於服務靜態內容來說[很好](http://wiki.dreamhost.com/Web_Server_Performance_Comparison)。 –