烧瓶

时间:2016-06-21 11:30:38

标签: python flask multiprocessing uwsgi gunicorn

我创建了一个烧瓶应用程序,它打开数据库连接并将一些数据存储在全局变量中。这些全局变量中的数据由页面中的后续ajax请求使用。但是我遇到了并发的严重问题。我尝试使用uwsgi和gunicorn来运行烧瓶应用程序(并且两者都得到了相同的结果)。这是我在两次运行中的配置

1)4名工人

2)multithreaded =烧瓶中的真。

当2个用户使用该应用程序时(返回的数据特定于用户输入的几个选项),会发生的情况是,有时来自其他用户请求的数据来自我的应用程序实例,有时反之亦然。

我的假设是我的应用程序获取其数据的工作人员不断变化。我对gunicorn和uwsgi的工人模型不太确定。有人能告诉我如何确保用户只获取他所请求的数据吗?(提醒:他请求的数据存储在python和ajax请求中的全局变量中,此对象传递给html)。任何帮助将非常感激。

我已经阅读了有关请求上下文的内容,但我完全不知道如何解决这个问题

@app.route("/"):
def redir():
    global a;
    #assume this is only for post(from a ajax call)
    a = #some data built from a database based on the options from the page where the post was made
    return jsondumps({'data':a[0:100]});

@app.route("/next100")
def next100():
    global a;
    # return the next 100 records of the global variable a.
    return jsondumps({'data':a[100:200]});

预期用户向redir()函数发出第一个ajax请求,然后在另一个ajax调用上调用next100()并返回数据。 当只有一个用户时,上述情况没有任何问题。

当有2个用户并且他们都调用了redir()并且当他们继续调用next100()时,两个用户都从全局“a”变量中随机获取数据(有时来自user1的上下文,有时来自user2的)

2 个答案:

答案 0 :(得分:2)

如果您要将某些内容存储为Web工作者中的全局内容,则最好确保该变量的生命周期以请求开始和结束。

另外,你得到的是你从请求中存储的东西,然后另一个请求可能带有不同的上下文(例如不同的用户),然后你的数据全部混淆。

如果需要在Web工作者之间共享某些内容,那么最好选择集中式数据存储(数据库,缓存,任何内容),因为这样您将被迫使用上下文来思考和标记每个数据。例如。在存储任何与用户相关的数据之前,您会考虑使用user_id = X

标记该行数据

你可能认为你可以通过附加用户信息的Flask全局实现相同的功能,但是当你考虑请求如何进入Web Worker 1时会出现故障,然后来自同一用户的另一个请求进入Web Worker 2,其中先前的数据不存在(全局仅限于Web Worker 1)。这是一些集中式数据存储区闪耀的情况。

答案 1 :(得分:1)

正如bakkal所指出的,全局变量在使用线程时会中断。

相反,您可以为用户提供包含您要保留的数据的Cookie:

session["a"] = "a" # or whatever

当然,这不会无限扩展,所以如果你有大量数据,你应该在cookie中存储一些(数据库)会话信息并从数据库加载信息。

有关flask.session的更多信息,请阅读the documentation

实际上,flask.g实际上是将单个请求中的信息传递给不同的函数,而不是从单个会话中的不同请求传递信息。

相关问题