Flask是否可以在小型API中共享全局变量?

时间:2018-11-02 14:25:16

标签: python flask global tornado

我正在尝试使用Flask和将在应用程序中共享的全局对象构建一个小型且快速的API(每个请求都可以检查该全局对象并搜索ID)。我不想使用db,redis或其他类似的解决方案:我只想要一些易于理解的内容。

例如下面的代码:(带有flask-restplus)

...
database = collections.defaultdict(int)

@ns.route('/')
class List(Resource):

  @ns.doc('list', description="Get id")
  def get(self):
     logger = logging.getLogger(__name__)
     database["TEST"] += 1
     logger.info(database["TEST"])
     return {"test": database["TEST"]}

2018-11-02 14:53:44,575 INFO       namespace:   48 -- 1
2018-11-02 14:53:44,712 INFO       _internal:   88 -- 127.0.0.1 - - [02/Nov/2018 14:53:44] "GET /workflow/ HTTP/1.1" 200 -
2018-11-02 14:53:44,720 INFO       namespace:   48 -- 2
2018-11-02 14:53:44,838 INFO       _internal:   88 -- 127.0.0.1 - - [02/Nov/2018 14:53:44] "GET /workflow/ HTTP/1.1" 200 -
2018-11-02 14:53:44,848 INFO       namespace:   48 -- 3
2018-11-02 14:53:44,935 INFO.      _internal:   88 -- 127.0.0.1 - - [02/Nov/2018 14:53:44] "GET /workflow/ HTTP/1.1" 200 -
2018-11-02 14:53:44,942 INFO       namespace:   48 -- 4
2018-11-02 14:53:45,044 INFO.      _internal:   88 -- 127.0.0.1 - - [02/Nov/2018 14:53:45] "GET /workflow/ HTTP/1.1" 200 -
2018-11-02 14:53:45,051 INFO.      namespace:   48 -- 5
2018-11-02 14:53:45,151 INFO.      _internal:   88 -- 127.0.0.1 - - [02/Nov/2018 14:53:45] "GET /workflow/ HTTP/1.1" 200 -
2018-11-02 14:53:45,158 INFO.      namespace:   48 -- 6
2018-11-02 14:53:45,256 INFO.      _internal:   88 -- 127.0.0.1 - - [02/Nov/2018 14:53:45] "GET /workflow/ HTTP/1.1" 200 -
2018-11-02 14:53:45,263 INFO.      namespace:   48 -- 7
2018-11-02 14:53:45,345 INFO.      _internal:   88 -- 127.0.0.1 - - [02/Nov/2018 14:53:45] "GET /workflow/ HTTP/1.1" 200 -
2018-11-02 14:53:45,360 INFO.      namespace:   48 -- 8
2018-11-02 14:53:45,469 INFO.      _internal:   88 -- 127.0.0.1 - - [02/Nov/2018 14:53:45] "GET /workflow/ HTTP/1.1" 200 -
2018-11-02 14:53:45,476 INFO.      namespace:   48 -- 9

正在运行,但我有几个问题:

  • 默认情况下,Flask在dev模式下仅限于一个线程。我尝试使用threaded = 3选项,它仍在工作。 我很幸运吗?在多线程环境中使用像这样的全局变量是不安全的吗?
  • 我希望我的应用程序尽可能小:我不想使用wsgi / redis / celery / ...处理许多请求。但是Flask似乎仅设计用于WSGI。启动Flask时收到的消息:    警告:请勿在生产环境中使用开发服务器。    请改用生产WSGI服务器。 我可以将Flask与开发服务器一起用于生产应用程序吗?还是一个好习惯吗?
  • 也许结论是我使用了错误的Web框架。 Tornado默认情况下是单线程和单进程,它将解决所有这些问题。你怎么看 ?我错了吗?

感谢您的帮助,

1 个答案:

答案 0 :(得分:0)

1)我想这取决于您如何使用此全局变量。唯一可以确定的是-您将不得不自己处理更改全局状态的线程。并发问题通常是您可能遇到的最讨厌的问题。对他们来说,最糟糕的事情是几乎没有办法测试它们,只设计它们。关于该主题有一篇不错的文章(这是针对Java的,但是我敢肯定,同样适用于python https://www.planetgeek.ch/2009/08/25/how-to-find-a-concurrency-bug-with-java/)。要点-全球人员不会简化事情。它们将使事情看起来简单,而使它们变得像地狱一样复杂。

2)好吧,您可以将开发服务器用于生产用途,但是为什么要这么做呢?在不知道您尝试开发的应用程序上下文的情况下,无法确定为此使用开发服务器的合理性,但是在大多数情况下,这是不可行的解决方案。

3)一切归结为您的最终目标。如果您想要多合一的框架,那么Tornado是一个不错的选择。不过,这不能解决全局变量的问题(例如,参见Tornado - Python global variable