【问题标题】:Flask get request have inconsistent returnFlask get 请求返回不一致
【发布时间】:2017-04-04 04:46:40
【问题描述】:

我使用 Flask 在 Heroku 上构建了一个迷你服务器。服务器端代码如下所示:

from flask import Flask
from flask_cors import CORS, cross_origin

app = Flask(__name__)

schedule = {'Basketball': 'old value'}

@app.route("/")
@cross_origin()
def get_all_schedule():
    return json.dumps(schedule)

@app.route("/update", method=['post'])
def update_basketball_schedule():
      globle schedule
      schedule['Basketball'] = 'new value'

if __name__ == "__main__":
    app.run(host='0.0.0.0')

我有一个全局字典schedule 来存储日程数据。我使用帖子/update URL 更新此时间表,并使用/ URL 获取数据,看起来很简单。

我正在我的 Chrome 浏览器上测试这个应用程序。我曾经调用过帖子网址。然后当我调用/ 时,有时它会返回带有"new value" 的字典,有时它会返回带有"old value" 的字典。这种行为的原因是什么?

我在 Heroku 上使用免费的测功机。

我的Procfile 包含:

web: gunicorn server:app

【问题讨论】:

  • 我也有同样的问题。你找到解决办法了吗?

标签: python heroku web flask server


【解决方案1】:

Heroku dynos 偶尔会重置、死亡或以其他方式禁用。因此,存储在内存中的所有变量的值都会丢失。为了解决这个问题,您可以使用 redis 或其他键/值存储来保存您的数据。

【讨论】:

  • 刚刚在谷歌上搜索了 Redis。 Redis 是内存中的数据结构存储,它也会受到 Heroku dyno 重置的影响吗?
  • 不,Heroku 提供了一个不受此影响的 redis 插件。详情请参阅add-on page
  • 非常感谢!
【解决方案2】:

我有一个全局字典schedule 来存储日程数据

你不能像这样依赖变量来维持状态。

对于初学者,Gunicorn will run with multiple processes by default:

Gunicorn 在每个 dyno 中分叉多个系统进程,以允许 Python 应用程序支持多个并发请求,而无需它们是线程安全的。在 Gunicorn 术语中,这些被称为工作进程(不要与 Heroku 工作进程混淆,后者在自己的 dyno 中运行)。

每个分叉的系统进程都会消耗额外的内存。这限制了您可以在单个测功机中运行的进程数。对于典型的 Django 应用程序内存占用,您可以期望在 freehobbystandard-1x dyno 上运行 2-4 个 Gunicorn 工作进程。您的应用程序可能允许对此进行更改,具体取决于您的应用程序的特定内存要求。

我们建议为此设置设置一个配置变量。 Gunicorn 自动接受 WEB_CONCURRENCY 环境变量(如果已设置)。

heroku config:set WEB_CONCURRENCY=3

WEB_CONCURRENCY 环境变量由 Heroku 根据进程的 Dyno 大小自动设置。此功能旨在为您的应用程序提供一个合理的起点。我们建议您了解进程的内存需求并相应地设置此配置变量。

您提出的每个请求都可以由任何 Gunicorn 工作人员处理。由于各种原因,将WEB_CONCURRENCY 设置为1 并不是正确的解决方案。例如,as Jake saysHeroku dynos restart frequently(至少每天一次)然后您的状态也会丢失。

幸运的是,Heroku 提供了a number of data store addons,包括像 Redis 这样的内存存储,这可能很适合这里。这将让您在所有 Gunicorn 工作人员和 dyno 重启之间共享状态。如果您需要以这种方式扩展应用程序,它甚至可以跨 dynos 工作。

【讨论】:

  • 如果我不想仅将 redis 用于该全局,我还能在我的 python 代码中做什么?因为在节点 js 中,我的朋友使用 map = new map(); 创建了相同的应用程序;这东西工作正常。
  • @BhaveshMevada,最好的办法是让你的状态脱离你的代码。您朋友的代码也是如此。但是要重现您朋友的行为,您可以将WEB_CONCURRENCY 设置为1,例如通过heroku config:set WEB_CONCURRENCY=1(尽管我强烈建议将您的状态存储在其他地方)。
  • 我可以使用 MySQL 来存储标志值吗?
  • @BhaveshMevada,是的。 Redis 将提供更好的性能,但任何客户端-服务器数据存储都可以工作。如果您已经有一个数据库,请随意使用它。
  • 先生,我可以在这里使用 g 对象吗?我在你建议的另一篇文章中看到了。
猜你喜欢
  • 2018-03-06
  • 2017-03-30
  • 1970-01-01
  • 1970-01-01
  • 2017-05-22
  • 2020-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多