【问题标题】:Nginx + uWsgi + Django strange json response behaviorNginx + uWsgi + Django 奇怪的 json 响应行为
【发布时间】:2011-11-26 18:53:43
【问题描述】:

一些技术规格:

  • CentOS 6.0
  • uWSGI 0.9.9.2
  • Nginx 1.0.5
  • Django 1.3.1

uWSGI:

    [uwsgi]
    socket = 127.0.0.1:3031
    master = true
    processes = 5
    uid = xx
    gid = xx
    env = DJANGO_SETTINGS_MODULE=xx.settings
    module = django.core.handlers.wsgi:WSGIHandler()
    post-buffering = 8192
    harakiri = 30
    harakiri-verbose = true
    disable-logging = true
    logto = /var/log/xx.log
    vacuum = true
    optimize = 2

JSON 序列化器:

class LazyEncoder(simplejson.JSONEncoder, json.Serializer):
    def default(self, obj):
        if isinstance(obj, Promise):
            return force_unicode(obj)
        if isinstance(obj, Decimal):
            u_value = force_unicode(obj)
            if u'.' in u_value:
                return float(u_value)
            return int(u_value)
        return super(lazy_encoder, self).default(obj)

JSON HttpResponse:

class JsonResponse(HttpResponse):
    status_code = 200
    json_status_code = 200
    message = _('OK')

    def __init__(self, json={}, *args, **kwargs):
        mimetype = kwargs.pop('mimetype', 'application/json')
        if not 'status' in json:
            json['status'] = {'code': self.json_status_code, 'message': self.message}
    super(JsonResponse, self).__init__(LazyEncoder(indent=settings.DEBUG and 4 or None, separators=settings.DEBUG and (', ', ': ') or (',', ':')).encode(json), mimetype=mimetype, *args, **kwargs)

我有一些 JsonResponse 的子类以及其他 json_status_code 和消息。

查看:

....
if application.status == Application.STATUS_REMOVED:
    return JsonApplicationSuspendedResponse()
....
return JsonResponse()

问题:

即使应用程序状态发生变化,我也会收到旧的 json,以免说 3 - 4 秒,然后它会正确返回 JsonApplicationSuspendedResponse()。

我检查了数据库应用程序状态更新是否立即发生, 还注意到,如果我重新启动 uWSGI 并发送请求响应是正确的,则会发生相反的情况。状态改变后的第二个请求可以有旧的json。

看起来他们写了几个秒的响应并且她的刷新有问题(缓存被禁用)。

有什么想法可能是问题所在?

相同的代码在 Apache2 和 mod_wsgi 上运行良好

固定

这是一个非常愚蠢的错误,在 JsonResponse 中我有:

def __init__(self, json={}, *args, **kwargs):

part json={} 在这里很重要,JsonResponse 和 init 之后的每个 JsonResponse 子类共享初始 dict 及其内容,所以答案看起来没有改变。

def __init__(self, json=None, *args, **kwargs):
    mimetype = kwargs.pop('mimetype', 'application/json')
    if not json:
        json = {}
    if not 'status' in json:
        json['status'] = {'code': self.json_status_code, 'message': self.message}

感谢您的宝贵时间

【问题讨论】:

  • 尝试在您的 GET 请求中添加时间戳变量。
  • 我试过了,不起作用我认为是服务器端的东西
  • uwsgi nginx module 有几个用于控制缓存的指令。据我所知,这不太可能是您的问题,默认情况下未启用缓存。
  • 我倾向于将这些事情默认归咎于 uwsgi,它真的很麻烦。试试 gunicorn,或者 uwsgi 0.9.6.8(这是我找到的最好的版本)
  • 请回答您的问题并进行验证。

标签: python django json nginx uwsgi


【解决方案1】:

您是否尝试过禁用 python 优化器(从 uWSGI 配置文件中删除优化选项)?

即使它看起来更像是一个 js/html/client 问题,某些对象可能会在启用优化的情况下造成某种混乱。并且请不要听从愚蠢的建议,例如降级到超过 1 年的不受支持的版本。

【讨论】:

  • 我已从 uWSGI 配置文件中删除优化器并清理所有 *.pyo、*.pyc 文件,但没有任何改变
  • 所以肯定是缓存问题。您可以尝试将 uWSGI 放在 apache 而不是 nginx 后面吗? (您可以毫无问题地沿 mod_wsgi 添加 mod_uwsgi)。这样我们就可以了解问题出在哪里了。
  • ...您可以做的另一个测试是通过 curl 直接向 nginx 询问 json 视图,因此您可以确定浏览器缓存不会发挥作用。您是否在嵌入模式和守护进程模式下都尝试过 mod_wsgi ? damon_mode 更类似于 uWSGI 方法
  • 现在它的 Nginx -> uWsgi (Emperor 模式) -> Django,在测试机器上我有 Apache2 -> mod_wsgi -> Django,我尝试通过 urllib 进行测试,我也为每个添加了时间戳请求(example.com/?20110927122345),但响应仍然看起来像“缓存”。我会试试apache2,我会告诉你的
  • 抱歉,忘记建议其他测试。如果您重新启用 uWSGI 日志记录,您将能够查看 json 请求是通过它还是在 nginx 处停止。
猜你喜欢
  • 1970-01-01
  • 2018-09-09
  • 2023-03-17
  • 2015-01-18
  • 1970-01-01
  • 1970-01-01
  • 2019-09-15
  • 1970-01-01
  • 2018-09-28
相关资源
最近更新 更多