У меня есть приложение WSGI, использующее CherryPy, размещенное с использованием uWSGI за сервером ngnix.Как я могу избежать 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;
}
uwsgi конфигурация в /etc/uwsgi/apps-enabled/sample.js
:
{
"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 и указать его на другую копию исходного кода, добавить дополнительный location /sample.test/ { ... }
в ngnix, указывая на новое приложение uwsgi, и взломать его с использованием альтернативного URL-адреса, не затрагивая производственную версию.
Но он использует uwsgi_modifier1 30
, который якобы уродливой хак:
http://uwsgi-docs.readthedocs.org/en/latest/Nginx.html
Примечание: древние версии uWSGI используются для поддержки так называемого «uwsgi_modifier1 30» подход. Не делай этого. это действительно некрасиво хак
Теперь я могу это сделать:
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-репо, проверенные на стабильные и девеловые ветви соответственно), возможно, играя в игры с 'sys.path'. virtualenv? – Celada
Однако спасибо за ваш ответ. Я сделал первое предложение об упрощении вещей. Я сохранил uWSGI, потому что его управление жизненным циклом, производительность, а также возможности настройки и мониторинга наилучшим образом подходят для нашего приложения, но я закончил удаление CherryPy из состава. Приложение имеет одну конечную точку URL-адреса, поэтому мне действительно ничего не нужно здесь, кроме необработанного WSGI ('def application (env, start_response)'), и если мне понадобится больше, то более легкая библиотека без собственного встроенного HTTP-сервера может быть более подходящий. – Celada
@Celada (1) Если экземпляр CherryPy, предназначенный для обслуживания как * stable *, так и * dev *, подвержен частым обновлениям от * dev *, тогда я разделяю вашу озабоченность. В таком случае я бы предложил заменить префикс пути субдоменом, например * dev.example.com *, * beta.example.com * и т. Д. Это также самый простой ответ OP. (2) Вы можете сделать * sys.path * hackery, чтобы импортировать версию того же модуля. Хотя только в крайнем случае. – saaj