Apache-2.2

Apache mpm worker + wsgi Python/Django worker 卡住了

  • June 13, 2014

我們的 Apache+Django 伺服器存在工人卡住的問題。這是一個 mpm 工作模式,一段時間後,每個服務於幾十個工作執行緒的程序都會凍結其所有工作人員:

# apache2ctl status
Apache Server Status for localhost

Server Version: Apache/2.2.14 (Ubuntu) mod_ssl/2.2.14 OpenSSL/0.9.8k mod_wsgi/
   2.8 Python/2.6.5
Server Built: Mar 8 2013 16:46:38

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Current Time: Friday, 05-Apr-2013 15:56:17 CEST
Restart Time: Thursday, 04-Apr-2013 11:23:23 CEST
Parent Server Generation: 11
Server uptime: 1 day 4 hours 32 minutes 53 seconds
Total accesses: 244313 - Total Traffic: 4.7 GB
CPU Usage: u181.45 s33.97 cu.62 cs0 - .21% CPU load
2.38 requests/sec - 47.9 kB/second - 20.2 kB/request
108 requests currently being processed, 42 idle workers

_K__K______KK_____W_________W________K_K__________..............
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW..............
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW..............
................................................................
................................................................
................................................................

Scoreboard Key:
"_" Waiting for Connection, "S" Starting up, "R" Reading Request,
"W" Sending Reply, "K" Keepalive (read), "D" DNS Lookup,
"C" Closing connection, "L" Logging, "G" Gracefully finishing,
"I" Idle cleanup of worker, "." Open slot with no current process

執行此操作時apache2ctl fullstatus,您可以看到正是兩個 PID 的所有工作人員都處於“工作”狀態。目前,PID 822 和 5284。而且,這些程序不滿足任何功能請求。此外,它們只能用信號 9 ( kill -9)殺死

該選項WSGIDaemonProcess cpu-time-limit=120/120對我們沒有幫助有兩個原因:只有 WSGI 3.0 和更高版本才有它,另外,程序不消耗 CPU,因此它們的 CPU 時間很短。

我們在伺服器上遇到了一些緩慢。它不是超級慢,但它可以更快(有時它掛在請求上),我懷疑這個問題是相關的。無論如何,它不應該是這樣的。

這是一個帶有 Apache 2.2.14 和 libapache2-mod-wsgi 2.8-2ubuntu1 的 Ubuntu 10.04 LTS 伺服器。網站服務如下:

WSGIScriptAlias / /srv/http/bla/passenger_wsgi.py

這是工人配置:

<IfModule mpm_worker_module>
   StartServers          2
   MinSpareThreads      25
   MaxSpareThreads      75
   ThreadLimit          64
   ThreadsPerChild      50
   MaxClients           200
   ServerLimit          6
   MaxRequestsPerChild  1000
</IfModule>

知道這是什麼以及如何解決嗎?或者,至少如何在這些程序上設置一些自動終止?Ulimit 很難,因為它們不會大量消耗 CPU。

前段時間我通過將站點轉換為使用守護程序模式而不是嵌入式模式來修復它,並在其前面放置一個 nginx 代理,它處理所有靜態文件服務。

由於各種原因,您的 MPM 設置有點損壞。建議你觀看我在 PyCon 上的演講:

至於您的伺服器掛起,您可能正在使用第三方擴展模組,從子解釋器中使用它是不安全的。您需要強制您的應用程序在主解釋器中執行。看:

要確定程序掛起的位置,另請參閱獲取堆棧跟踪的方法,如下所述:

如果它是預期的死鎖並且不想只嘗試使用主解釋器,則可能需要使用 gdb 來獲取卡住位置的堆棧跟踪。

如果問題是您的程式碼阻塞了對外部服務的呼叫,那麼 Python 堆棧跟踪方法將起作用。您也可以通過使用 lsof 或 ofiles 查看打開的文件描述符來了解這一點。

引用自:https://serverfault.com/questions/496491