如何避免uwsgi_modifier1 30并使WSGI保持与应用程序位置无关? [英] How can I avoid uwsgi_modifier1 30 and keep WSGI my application location-independent?

查看:61
本文介绍了如何避免uwsgi_modifier1 30并使WSGI保持与应用程序位置无关?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用CherryPy的WSGI应用程序,该应用程序在ngnix服务器后面托管了 uWSGI .

I have a WSGI application using CherryPy hosted using uWSGI behind a ngnix server.

我希望应用程序本身是便携式的".也就是说,应用程序不应该知道或不在乎它映射到哪个URL,甚至在映射到多个不同的URL时也应该可以工作.我想通过仅将URL映射信息保留在一个位置来 DRY .不幸的是,我发现这样做的唯一方法是使用 uwsgi_modifier 30 ,它被称为丑陋的骇客.我可以避免这种黑客攻击吗?

I would like for the application itself to be "portable". That is, the application should not know or care what URL it is mapped to, and should even work if mapped to multiple different URLs. I want to DRY by keeping the URL mapping information in one place only. Unfortunately, the only way I have found to do this involves using uwsgi_modifier 30, which has been called an ugly hack. Can I avoid that hack?

出于目前的目的,我创建了一个名为 sample 的微型应用程序,用于演示我的问题.

For the present purposes, I have created a tiny application called sample that demonstrates my question.

ngnix配置如下:

The ngnix config looks like this:

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配置:

The uwsgi config in /etc/uwsgi/apps-enabled/sample.js:

{
    "uwsgi": {
        "uid": "nobody",
        "gid": "www-data",
        "module": "sample:app"
    }
}

...以及应用程序本身:

...and the application itself:

#!/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 之后出现的内容:

  • The URL under which the application is mapped (/sample) appears only in one place: in the ngnix config file.
  • The application does not see that prefix and does not have to worry about it, it only receives whatever appears after /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上指向新的uwsgi应用程序添加一个额外的 location/sample.test/{...} 使用备用网址对其进行修改,而不会影响生产版本.

To motivate the reason for my question, let's say I have a development version of the application. I can make a second uwsgi app and point it to a different copy of the source code, add an extra location /sample.test/ { ... } to ngnix pointing to the new uwsgi app, and hack on it using the alternate URL without affecting the production version.

但是它利用了 uwsgi_modifier1 30 ,据说这是一个丑陋的骇客:

But it makes use of uwsgi_modifier1 30 which is supposedly an ugly hack:

http://uwsgi-docs.readthedocs.org/en/latest/Nginx.html

注意:古老的uWSGI版本用于支持所谓的"uwsgi_modifier1 30"方法.不要做.这是一个非常丑陋的骇客

Note: ancient uWSGI versions used to support the so called "uwsgi_modifier1 30" approach. Do not do it. it is a really ugly hack

现在,我可以这样做:

location /something/ {
    uwsgi_pass unix:/run/uwsgi/app/sample/socket; 
    include uwsgi_params;
}

...还有这个...

...and this...

{
    "uwsgi": {
        "uid": "nobody",
        "gid": "www-data",
        "pythonpath": "",  # no idea why I need this, btw
        "mount": "/something=sample:app",
        "manage-script-name": true
    }
}

但是它要求我在2个地方而不是1个地方对路径(/something )进行硬编码.可以避免吗?还是我应该坚持使用 uwsgi_modifier1 30 的原始设置?

But it requires that I hardcode the path (/something) in 2 places instead of 1. Can I avoid that? Or should I stick with the original setup which uses uwsgi_modifier1 30?

推荐答案

我的回答实际上是关于简化事情,因为以下内容和您拥有的配置数量表明一件事-过度杀伤.

My answer is really about simplifying things, because the following and the amount of configuration you have indicates one thing -- overkill.

CherryPy ⇐ WSGI ⇒ uWSGI ⇐ uwsgi ⇒ Nginx ⇐ HTTP ⇒ Client

CherryPy的生产就绪型服务器本地使用HTTP.不需要中介协议,即WSGI.对于低流量,您可以单独使用它.对于前排Nginx的高流量,例如:

CherryPy has production ready server that natively speaks HTTP. No intermediary protocol, namely WSGI, is required. For low traffic you can use it on its own. For high traffic with Nginx in front, like:

CherryPy ⇐ HTTP ⇒ Nginx ⇐ HTTP ⇒ Client

CherryPy具有应用程序概念,您可以服务多个应用程序和一个CherryPy实例.CherryPy还可以提供其他 WSGI的服务应用程序.最近,我回答了一个相关问题.

CherryPy has notion of an application and you can serve several applications with one CherryPy instance. CherryPy also can serve other WSGI applications. Recently I answer a related question.

CherryPy本地支持您正在谈论的可移植性.这意味着您可以将应用程序安装到给定的路径前缀,而无需进行其他配置(只要您使用 cherrypy.url 构建URL,并且通常要记住该应用程序可以安装到不同的路径前缀).

The portability your are talking about is natively supported by CherryPy. That means you can mount an app to a given path prefix and there's nothing else to configure (well, as long as you build URLs with cherrypy.url and generally keep in mind that the app can be mounted to different path prefixes).

server.py

#!/usr/bin/env python3

import cherrypy


config = {
  'global' : {
    'server.socket_host' : '127.0.0.1',
    'server.socket_port' : 8080,
    'server.thread_pool' : 8
  }
}
# proxy tool is optional
stableConf = {'/': {'tools.proxy.on': True}}
develConf  = {'/': {'tools.proxy.on': True}}

class AppStable:

  @cherrypy.expose
  def index(self):
    return 'I am stable branch'

class AppDevel:

  @cherrypy.expose
  def index(self):
    return 'I am development branch'    

cherrypy.config.update(config)
cherrypy.tree.mount(AppStable(), '/stable', stableConf)
cherrypy.tree.mount(AppDevel(), '/devel', develConf)    

if __name__ == '__main__':
  cherrypy.engine.signals.subscribe()
  cherrypy.engine.start()
  cherrypy.engine.block()

server.conf (可选)

server {
  listen  80;

  server_name localhost;

  # settings for serving static content with nginx directly, logs, ssl, etc.

  location / {
    proxy_pass         http://127.0.0.1:8080;
    proxy_set_header   Host             $host;
    proxy_set_header   X-Real-IP        $remote_addr;
    proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
  }

}

这篇关于如何避免uwsgi_modifier1 30并使WSGI保持与应用程序位置无关?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆