2009-08-27 26 views
6

我試圖用WSGI在Apache(prefork)中運行Python應用程序,以便使用單個Python解釋器。這是必要的,因爲應用程序使用線程同步來防止競爭條件的發生。由於Apache prefork衍生出多個進程,因此代碼不會在解釋器之間共享,因此線程同步無關緊要(即每個線程只能看到自己的鎖,而這些鎖對其他進程沒有影響)。在Apache Prefork/WSGI中共享Python解釋器

這裏是設置:

  • 阿帕奇2.0(prefork)的
  • WSGI
  • Python 2.5的

這裏是Apache的相關的配置:

WSGIApplicationGroup %{GLOBAL} 
<VirtualHost _default_:80> 

WSGIScriptAlias//var/convergedsecurity/apache/osvm.wsgi 

Alias /admin_media/ /var/www/html/admin_media/ 

<Directory /var/www/html/admin_media> 
Order deny,allow 
Allow from all 
</Directory> 

Alias /media/ /var/www/html/media/ 

<Directory /var/www/html/media> 
Order deny,allow 
Allow from all 
</Directory> 

</VirtualHost> 

這裏是我到目前爲止嘗試過的(沒有whi CH工作):

  1. 添加WSGIApplicationGroup %{GLOBAL}
  2. 虛擬主機內指定WSGIDaemonProcessWSGIProcessGroup

    WSGIDaemonProcess OSVM線程= 50
    WSGIProcessGroup OSVM

是沒有辦法強制Apache prefork在WSGI中使用單個Python解釋器?這些文檔似乎意味着您可以使用WSGIDaemonProcess和WSGIApplicationGroup選項,但是Apache仍然爲每個進程創建一個單獨的Python解釋器。

回答

9

無論是prefork還是worker MPM,您都無法在UNIX系統上以嵌入模式運行WSGI應用程序,因爲實際上會有多個進程。請參閱:

http://code.google.com/p/modwsgi/wiki/ProcessesAndThreading

創建由單個進程和委託WSGI應用應該達到你想要的東西的守護進程組。如果只有一個正在討論的WSGI應用程序,那麼您甚至不需要使用WSGIApplicationGroup。如果你想絕對確定,你也可以設置它。

因此內虛擬主機配置是:

WSGIDaemonProcess osvm 
WSGIProcessGroup osvm 
WSGIApplicationGroup %{GLOBAL} 

WSGIScriptAlias//var/convergedsecurity/apache/osvm.wsgi 

雖然「過程= 1」 WSGIDaemonProcess使得它明確所創建的一個過程中,不提供但選擇就讓它默認爲一個過程。任何'進程'選項的使用,即使對於一個進程,都會將'wsgi.multiprocess'設置爲True。

與其使用您的實際WSGI應用程序,我建議您使用以下簡單測試程序進行測試。

import cStringIO 
import os 

def application(environ, start_response): 
    headers = [] 
    headers.append(('Content-Type', 'text/plain')) 
    write = start_response('200 OK', headers) 

    input = environ['wsgi.input'] 
    output = cStringIO.StringIO() 

    print >> output, "PID: %s" % os.getpid() 
    print >> output 

    keys = environ.keys() 
    keys.sort() 
    for key in keys: 
     print >> output, '%s: %s' % (key, repr(environ[key])) 
    print >> output 

    output.write(input.read(int(environ.get('CONTENT_LENGTH', '0')))) 

    return [output.getvalue()] 

在輸出中,PID值應該始終相同。 wsgi.multiprocess標誌應該是False。 mod_wsgi。process_group的值應該是你所稱的守護進程組。而mod_wsgi.application_group應該是一個空字符串。

如果這不是您所看到的,請確保在進行配置更改後實際重新啓動Apache。另外,請將

LogLevel debug 

複製到適用於VirtualHost的Apache配置。這樣做會使mod_wsgi在Apache錯誤日誌中記錄更多關於進程創建和腳本加載的消息,包括正在發生的進程組和應用程序組的詳細信息。

有關調試的其他信息,請參見:

http://code.google.com/p/modwsgi/wiki/DebuggingTechniques

如果仍然存在問題,建議你去上谷歌論壇的mod_wsgi的郵件列表。

+0

謝謝你,你的回答是完美的。一旦我建立了守護進程組,我就遇到了幾個問題;兩者都是通過您在Google小組上提供的信息解決的。 具體來說,我必須在Apache配置(http://code.google.com/p/modwsgi/issues/detail?id=40)中提前提供User和Group指令並設置WSGISocketPrefix。 謝謝你的幫助。 – 2009-08-27 19:27:01