Flask 中每个客户请求的单独数据
Separate data per client request in flask
我创建了一个 flask 应用程序,它打开数据库连接并将一些数据存储在全局变量中。这些全局变量中的数据被页面中后续的 ajax 请求使用。然而,我 运行 正在处理严重的并发问题。我尝试同时使用 uwsgi 和 gunicorn 来 运行 flask 应用程序(并且两者都得到了相同的结果)。这是我在 运行 和
中的配置
1) 4 名工人
2) 多线程 = 在烧瓶中是正确的。
当 2 个用户使用该应用程序时(返回的数据特定于用户输入的几个选项),发生的情况是有时另一个用户请求的数据会进入我的应用程序实例有时相反。
我的假设是我的应用程序从中获取数据的工作器不断变化。我对 gunicorn 和 uwsgi 中的 worker 模型不是很确定。有人能告诉我如何确保用户只获得他请求的数据吗?(提醒:他请求的数据存储在 python 和 [=32= 中的全局变量中] 请求,此对象被传递给 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() 并且它 returns 数据。
当只有一个用户时,上述情况没有任何问题。
当有 2 个用户并且他们都调用了 redir() 并且当他们继续调用 next100() 时,两个用户随机从全局 "a" 变量中获取数据(有时来自用户 1 的上下文,有时来自用户 2 的)
如果您要将某些内容作为全局变量存储在您的网络工作者中,您最好确保该变量的生命周期以请求开始和结束。
否则你得到的是你从一个请求中存储了一些东西,然后另一个请求可能具有不同的上下文(例如不同的用户),然后你的数据都混在一起了。
如果需要在您的网络工作者之间共享某些内容,最好选择集中式数据存储(数据库、缓存等),因为那样您将被迫思考并标记每条数据语境。例如。在存储任何与用户相关的数据之前,您会想到用 user_id = X
标记该行数据
您可能认为您可以使用附加了用户信息的 Flask 全局实现同样的事情,但是当您考虑一个请求如何发送到 Web Worker 1,然后来自同一用户的另一个请求时,这种情况就不成立了转到先前数据不存在的 Web Worker 2(全局仅限于 Web Worker 1)。在这种情况下,某些集中式数据存储会大放异彩。
正如 bakkal 指出的那样,全局变量在使用线程时会中断。
相反,您可以为用户提供一个包含您要保留的数据的 cookie:
session["a"] = "a" # or whatever
当然这不会无限扩展,因此如果您有大量数据,您应该在 cookie 中存储一些(数据库)会话信息并从数据库加载信息。
有关 flask.session 的更多信息,请阅读 the documentation。
flask.g实际上是在单个请求中从不同的函数中传递信息,而不是在单个会话中从不同的请求中传递信息。
我创建了一个 flask 应用程序,它打开数据库连接并将一些数据存储在全局变量中。这些全局变量中的数据被页面中后续的 ajax 请求使用。然而,我 运行 正在处理严重的并发问题。我尝试同时使用 uwsgi 和 gunicorn 来 运行 flask 应用程序(并且两者都得到了相同的结果)。这是我在 运行 和
中的配置1) 4 名工人
2) 多线程 = 在烧瓶中是正确的。
当 2 个用户使用该应用程序时(返回的数据特定于用户输入的几个选项),发生的情况是有时另一个用户请求的数据会进入我的应用程序实例有时相反。
我的假设是我的应用程序从中获取数据的工作器不断变化。我对 gunicorn 和 uwsgi 中的 worker 模型不是很确定。有人能告诉我如何确保用户只获得他请求的数据吗?(提醒:他请求的数据存储在 python 和 [=32= 中的全局变量中] 请求,此对象被传递给 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() 并且它 returns 数据。 当只有一个用户时,上述情况没有任何问题。
当有 2 个用户并且他们都调用了 redir() 并且当他们继续调用 next100() 时,两个用户随机从全局 "a" 变量中获取数据(有时来自用户 1 的上下文,有时来自用户 2 的)
如果您要将某些内容作为全局变量存储在您的网络工作者中,您最好确保该变量的生命周期以请求开始和结束。
否则你得到的是你从一个请求中存储了一些东西,然后另一个请求可能具有不同的上下文(例如不同的用户),然后你的数据都混在一起了。
如果需要在您的网络工作者之间共享某些内容,最好选择集中式数据存储(数据库、缓存等),因为那样您将被迫思考并标记每条数据语境。例如。在存储任何与用户相关的数据之前,您会想到用 user_id = X
标记该行数据您可能认为您可以使用附加了用户信息的 Flask 全局实现同样的事情,但是当您考虑一个请求如何发送到 Web Worker 1,然后来自同一用户的另一个请求时,这种情况就不成立了转到先前数据不存在的 Web Worker 2(全局仅限于 Web Worker 1)。在这种情况下,某些集中式数据存储会大放异彩。
正如 bakkal 指出的那样,全局变量在使用线程时会中断。
相反,您可以为用户提供一个包含您要保留的数据的 cookie:
session["a"] = "a" # or whatever
当然这不会无限扩展,因此如果您有大量数据,您应该在 cookie 中存储一些(数据库)会话信息并从数据库加载信息。
有关 flask.session 的更多信息,请阅读 the documentation。
flask.g实际上是在单个请求中从不同的函数中传递信息,而不是在单个会话中从不同的请求中传递信息。