Nginx + uWsgi + Django 奇怪的 JSON 响应行为

1 投票
1 回答
1879 浏览
提问于 2025-04-17 03:15

一些技术规格:

  • 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):

这里json={}这一部分非常重要,JsonResponse及其每个子类在初始化后共享初始字典及其内容,所以响应看起来没有变化。

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}

感谢你的时间

1 个回答

0

你有没有试过关闭Python的优化功能(把uWSGI配置文件里的优化选项去掉)?

即使看起来更像是JavaScript、HTML或者客户端的问题,有些对象在开启优化的情况下可能会搞出一些麻烦。而且,请不要听那些傻建议,比如降级到不再支持的、超过一年没更新的版本。

撰写回答