【问题标题】:Concurrency-safe way to initialize global data connections in Flask在 Flask 中初始化全局数据连接的并发安全方法
【发布时间】:2019-01-16 10:24:09
【问题描述】:

全局变量是 Flask 中的not thread-safe or "process-safe"

但是,我需要打开与每个工作人员将使用的服务的连接,例如 PubSub 客户端或 Cloud Storage 客户端。似乎这些仍然需要是全局的,以便应用程序中的任何功能都可以访问它们。为了懒惰地初始化它们,我检查变量是否为None,这需要是线程安全的。打开每个请求将使用的连接的推荐方法是什么?我应该使用线程锁来同步吗?

【问题讨论】:

    标签: python multithreading flask


    【解决方案1】:

    The question you linked 谈论的是数据,而不是连接。让多个工作人员改变全局数据并不好,因为您无法推断这些工作人员在 Web 应用程序中的位置以使它们保持同步。

    该问题的解决方案是使用必须以某种方式连接到的外部数据源,例如数据库。但是,您拥有一个全局连接的想法并不安全,因为多个工作线程会同时与其交互,并且要么混淆彼此的状态,要么一次等待一个来获取资源。处理此问题的最简单方法是在需要时在每个视图中建立连接。


    此示例说明如何在没有全局变量的情况下为每个请求建立一个唯一连接,并在为请求建立连接后重用该连接。 g 对象虽然看起来像一个全局对象,但在幕后实现为本地线程,因此每个工作人员仅在一次请求期间获取其自己的 g 实例和存储在其上的连接。

    from flask import g
    
    def get_conn():
        """Use this function to establish or get the already established
        connection during a request. The connection is closed at the end
        of the request. This avoids having a global connection by storing
        the connection on the g object per request.
        """
        if "conn" not in g:
            g.conn = make_connection(...)
    
        return g.conn
    
    @app.teardown_request
    def close_conn(e):
        """Automatically close the connection after the request if
        it was opened.
        """
        conn = g.pop("conn", None)
    
        if conn is not None:
            conn.close()
    
    @app.route("/get_data")
    def get_data():
        # If something else has already used get_conn during the
        # request, this will return the same connection. Anything
        # that uses it after this will also use the same connection.
        conn = get_conn()
        data = conn.query(...)
        return jsonify(data)
    

    一旦您有成千上万个并发请求,您最终可能会发现为每个请求建立一个新连接的成本太高了。一种解决方案是构建一个连接池来全局存储连接列表,并使用线程安全的方式根据需要获取和替换列表中的连接。 SQLAlchemy(和 Flask-SQLAlchemy)使用这种技术。许多库已经提供了连接池实现,所以要么使用它们,要么将它们用作你自己的参考。

    【讨论】:

      猜你喜欢
      • 2022-10-20
      • 1970-01-01
      • 2010-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-08
      • 1970-01-01
      相关资源
      最近更新 更多