我有一個WSGI應用程序使用CherryPy在ngnix服務器後面使用uWSGI託管。如何避免uwsgi_modifier1 30並保持我的應用程序位置無關的WSGI?
我希望應用程序本身是「便攜」的。也就是說,應用程序不應該知道或關心它映射到的URL,甚至應該映射到多個不同的URL。我想DRY只保留URL映射信息在一個地方。不幸的是,我發現要做到這一點的唯一方法是使用uwsgi_modifier 30
,其中has been called an ugly hack。我可以避免這種黑客行爲嗎?
就目前而言,我創建了一個名爲sample
的小應用程序來演示我的問題。
的ngnix配置是這樣的:
location /sample/ {
uwsgi_pass unix:/run/uwsgi/app/sample/socket;
include uwsgi_params;
uwsgi_param SCRIPT_NAME /sample;
uwsgi_modifier1 30;
}
在/etc/uwsgi/apps-enabled/sample.js
的uwsgi配置:
{
"uwsgi": {
"uid": "nobody",
"gid": "www-data",
"module": "sample:app"
}
}
...和應用程序本身:
#!/usr/bin/python
import cherrypy
class Root(object):
@cherrypy.expose
def default(self, *path):
return "hello, world; path=%r\n" % (path,)
app = cherrypy.Application(Root(), script_name=None)
它的工作原理:
- 應用程序映射到的URL(
/sample
)只出現在一個地方:在ngnix配置文件中。 應用程序沒有看到前綴,不必擔心,它只是接收任何出現
/sample
後:$ curl http://localhost/sample/ hello, world; path=() $ curl http://localhost/sample/foo hello, world; path=('foo',) $ curl http://localhost/sample/foo/bar hello, world; path=('foo', 'bar')
爲了激勵我的問題的原因,讓我們說我有該應用程序的開發版本。我可以製作第二個uwsgi應用程序,並將其指向另一個源代碼副本,爲ngnix添加一個額外的location /sample.test/ { ... }
指向新的uwsgi應用程序,並在不影響生產版本的情況下使用備用URL對其進行破解。
但它利用uwsgi_modifier1 30
按理說它是一個醜陋的黑客攻擊:
http://uwsgi-docs.readthedocs.org/en/latest/Nginx.html
注:用於支持所謂的「uwsgi_modifier1 30」的做法古uWSGI版本。不要做。它確實是一個醜陋的黑客
現在,我可以這樣做:
location /something/ {
uwsgi_pass unix:/run/uwsgi/app/sample/socket;
include uwsgi_params;
}
...這...
{
"uwsgi": {
"uid": "nobody",
"gid": "www-data",
"pythonpath": "", # no idea why I need this, btw
"mount": "/something=sample:app",
"manage-script-name": true
}
}
但是,它需要的是我硬編碼的路徑( /something
)在2個地方而不是1個。我可以避免這種情況嗎?還是應該堅持使用uwsgi_modifier1 30
的原始設置?
,那麼就表明安裝在一個單一的CherryPy過程既穩定版和開發版的第二部分,我肯定有這樣的擔憂,因爲(1)CherryPy實例將隨着開發的進行而需要重新啓動,同時不必要地影響穩定版本,(2)它有點棘手首先要做的事情,因爲我不得不在相同的Python過程中導入兩次相同的模塊(例如,兩個不同的同一個git repo的克隆,分別檢查出穩定和devel分支),也許通過使用'sys.path'玩遊戲。的virtualenv? – Celada
不過謝謝你的回答。我把第一句話簡單化了一下。我保留了uWSGI,因爲它的生命週期管理,性能,調整和監視功能最適合我們的應用程序,但我最終從混合中刪除了CherryPy。該應用程序有一個單一的URL端點,所以除了原始的WSGI('def application(env,start_response)')之外,我真的不需要任何東西,如果我確實需要更多,那麼沒有自己的內置HTTP服務器的更輕的庫可能更加合適。 – Celada
@Celada(1)如果是指CherryPy的實例同時服務於*穩定*和* dev的*是受到來自*開發*頻繁的更新,然後我分享你的關心。在這種情況下,我會建議用一個子域替換路徑前綴,比如* dev.example.com *,* beta.example.com *等。它也是OP的最簡單答案。 (2)你一定可以做* sys.path * hackery來導入相同模塊的版本。雖然只是作爲最後的手段。 – saaj