Firebase Firestore get() 快照在第二次查询时冻结

Posted

技术标签:

【中文标题】Firebase Firestore get() 快照在第二次查询时冻结【英文标题】:Firebase Firestore get() snapshot freezes on second query 【发布时间】:2018-12-05 08:12:39 【问题描述】:

我正在尝试从 AWS Elastic Beanstalk 部署中访问 Firestore。 EB 应用程序是使用 Python 中的 Flask 编写的,并且在本地一切正常。但是,当我尝试部署到 EB 时,只有第一个数据库请求成功——第二个数据库请求在调用 .get() 期间冻结了我的应用程序。

我不确定这是 EB 上的权限问题、Firestore 问题还是什么!由于没有抛出异常,我什至无法拒绝请求并继续前进。

我确实在日志中得到以下信息:

[Tue Jun 26 11:29:16.964989 2018] [core:error] [pid 3914] [client 172.31.17.165:22711] Script timed out before returning headers: application.py

...但那是因为对 .get() 的调用永远不会返回,导致脚本超时。

这是我的这个测试应用的完整代码:

import os

from flask import Flask, url_for, redirect, render_template
import mimetypes
import time

import google
import firebase_admin
from firebase_admin import credentials
from firebase_admin import firestore

print("=====================================================")
print("initializing app")
cred = credentials.Certificate("/my/actual/path/to/credentials/is/here.json")
firebase_admin.initialize_app(cred)
print("done.")

print("initializing firestore")
db = firestore.client()
print("done.")

print("initializing flask")
application = Flask(__name__)
print("done.")

@application.route('/doc/<docId>')
def doc(docId):
    docId = docId.lower()

    documents_ref = db.collection(u'documents')
    doc_ref = documents_ref.document(docId)

    print("getting doc")
    doc = None
    try:
        doc = doc_ref.get()
    except google.cloud.exceptions.NotFound:
        print("not found.")
        return render_template('doc.html', message="This document no longer exists ????.")
    print("done.")

    # Here is where I'd normally use the DB snapshot data, but omitted for the question
    creatorStr = "Someone"
    timeStr = "a time"

    docMessage = creatorStr + " sent you a document dated " + timeStr + "."

    return render_template('doc.html', docMessage=docMessage)

if __name__ == "__main__":
    # application.debug = True
    application.run()

任何帮助将不胜感激!

【问题讨论】:

Beanstalk 日志可能会告诉您问题所在。通过控制台,您可以下载完整的捆绑日志并查看其中是否有明显的内容。通过 EBCLI,您可以执行eb logs 相同的操作。如果日志中没有任何指示,我建议通过 SSH 连接到 beanstalk 实例并在那里手动运行应用程序。我认为您应该在/var/lib/current 下找到该应用程序。 日志没有显示任何感兴趣的内容,似乎...错误日志中的最后一条消息是从脚本中“获取文档”,然后在超时之前什么都没有。 我正在试图弄清楚如何通过 SSH 连接到实例以手动运行它...我认为 python 应用程序位于 /opt/python/current 中,我可以使用 flask run 启动它,但是我仍在尝试弄清楚如何从外部访问实例以进行测试。 好的,我连接到带有eb sshsource /opt/python/current/envflask run 的实例,并在端口5000 上启动了实例上的烧瓶服务器。然后,我用@ 对其进行了测试987654332@,它似乎每次都在那里工作。所以问题似乎不是访问外部世界的实例?或者,EB 运行烧瓶服务器与我运行时有什么不同? 所以问题似乎不是访问外部世界的实例? - 很可能是这种情况。您能否确定与环境关联的 EC2 实例是否允许 5000 上的传入流量通过其安全组?您能告诉我您的环境使用的是哪种负载均衡器吗? 【参考方案1】:

好的,我终于找到了解决问题的方法: AWS Elastic Beanstalk - Script timed out before returning headers: application.py

像这样创建一个 ebextension 文件并重新部署以解决问题:

nano .ebextensions/<some_name>.config 

#add the following to <some_name>.config 
files:
  "/etc/httpd/conf.d/wsgi_custom.conf":
    mode: "000644"
    owner: root
    group: root
    content: |
      WSGIApplicationGroup %GLOBAL


#add to git
git add .ebextensions/<some_name>.config
git commit -m 'message here'

#deploy to beanstalk
eb deploy

【讨论】:

以上是关于Firebase Firestore get() 快照在第二次查询时冻结的主要内容,如果未能解决你的问题,请参考以下文章

Firebase Firestore get() 快照在第二次查询时冻结

如何使用 Firebase Firestore 获取子集合? [复制]

Firebase 存储规则在 Firestore 文档上查找数据? [复制]

使用规则禁用 Firebase Cloud Firestore 中的查询集合

在 Firebase Firestore 中映射集合快照项

如果文档使用大型 Map 字段,则 Firebase Firestore 查询错误