简体   繁体   English

Firebase 查询 AWS RDS PostgreSQL 数据库时函数超时

[英]Firebase Functions timeout when querying AWS RDS PostgreSQL database

I am trying to query an Amazon RDS database from a Firebase Node JS cloud function.我正在尝试从 Firebase 节点 JS 云 function 查询 Amazon RDS 数据库。 I built the query and can successfully run the code locally using firebase functions:shell .我构建了查询,并且可以使用firebase functions:shell However, when I deploy the function and call it from client-side js on my site I receive errors on both the client and server side.但是,当我部署 function 并从我网站上的客户端 js 调用它时,我在客户端和服务器端都收到错误。

Client-side:客户端:

Error: internal
Origin http://localhost:5000 is not allowed by Access-Control-Allow-Origin.
Fetch API cannot load https://us-central1-*****.cloudfunctions.net/query due to access control checks.
Failed to load resource: Origin http://localhost:5000 is not allowed by Access-Control-Allow-Origin.

Server-side:服务器端:

Function execution took 60004 ms, finished with status: 'timeout'

I believe the issue has two parts:我认为这个问题有两个部分:

  1. CORS CORS
  2. pool.query() is async pool.query()是异步的

I have looked at multiple questions for a CORS solution, here and here for example, but none of the solutions have worked for me.我已经查看了 CORS 解决方案的多个问题,例如这里这里,但没有一个解决方案对我有用。 In regards to pool.query() being async I believe I am handling it correctly however neither the result nor an error is printed to the servers logs.关于pool.query()是异步的,我相信我正在正确处理它,但是结果和错误都不会打印到服务器日志中。

Below is all the relevant code from my projects.以下是我项目中的所有相关代码。

Client-side:客户端:

var queryRDS = firebase.functions().httpsCallable('query');
queryRDS({
     query: document.getElementById("search-input").value
})
.then(function (result) {
     if (result) {
          console.log(result)
     }
})
.catch(function (error) {
     console.log(error);
});

Server-side:服务器端:

const functions = require('firebase-functions');
const { Pool } = require('pg');

const pool = new Pool({
    user: 'postgres',
    host: '*****.*****.us-west-2.rds.amazonaws.com',
    database: '*****',
    password: '*****',
    port: 5432
})

exports.query = functions.https.onCall((data, context) => {
     // This is not my real query, I just changed it for the
     // simplicity of this question
     var query = "Select * FROM table"

     pool.query(query)
          .then(result_set => {
               console.log(result_set)
               return result_set
          }).catch(err => {
               console.log(err)
               return err
          })
})

I know everything works up until pool.query() , based on my logs it seems that the .then() or the .catch() are never reached and the returns never reach the client-side.我知道在pool.query()之前一切正常,根据我的日志,似乎永远不会到达 .then( .then().catch()并且返回永远不会到达客户端。

Update:更新:

I increased the timeout of the Firebase Functions from 60s to 120s and changed my server function code by adding a return statment before pool.query() :我将 Firebase 函数的超时时间从 60 秒增加到 120 秒,并通过在pool.query()之前添加一个返回语句来更改我的服务器 function 代码:

return pool.query(query)
     .then(result_set => {
          console.log(result_set)
          return result_set
     }).catch(err => {
          console.log("Failed to execute query: " + err)
          return err
     })

I now get an error message reading Failed to execute query: Error: connect ETIMEDOUT **.***.***.***:5432 with the IP address being my AWS RDS database.我现在收到一条错误消息,读取Failed to execute query: Error: connect ETIMEDOUT **.***.***.***:5432 with the IP address is my AWS RDS database。 It seems this might have been the underlying problem all along, but I am not sure why the RDS is giving me a timeout.似乎这一直是潜在的问题,但我不确定为什么 RDS 给我一个超时。

The CORS should be automatically handled by the onCall handler. CORS 应由onCall处理程序自动处理。 The error message about CORS is likely to be inaccurate, and a result of the function timing out, as the server side error is showing.关于 CORS 的错误消息可能不准确,并且是由于服务器端错误显示 function 超时导致的。

That being said, according to the Cloud Functions Documentation on Function's Timeout , the default timeout for Cloud Functions is of 60 seconds, which translated to the ~60000 ms on your error message, and this means that 1 minute is not enough for your function to execute such query, which makes sense if your consider that the function is accessing an external provider, which is the Amazon RDS database.话虽如此,根据 Cloud Functions Documentation on Function's Timeout ,Cloud Functions 的默认超时时间为 60 秒,在您的错误消息中转换为 ~60000 毫秒,这意味着 1 分钟对于您的 function 来说是不够的执行这样的查询,如果您认为 function 正在访问外部提供程序,即 Amazon RDS 数据库,那么这是有意义的。

In order to fix it you will have to redeploy your function with a flag for setting the function execution timeout, as follows:为了修复它,您必须重新部署您的 function 并带有一个用于设置 function 执行超时的标志,如下所示:

gcloud functions deploy FUNCTION_NAME --timeout=TIMEOUT

The Value of TIMEOUT could be anything until 540, which is the maximum seconds that Cloud Functions allows before timeout (9 minutes). TIMEOUT的值可以是 540 之前的任何值,这是 Cloud Functions 在超时前允许的最大秒数(9 分钟)。

NOTE : This could also be mitigated by deploying your function to the closest location possible to where your Amazon RDS database is located, you can check this link on what locations are available for Cloud Functions and you can use --region=REGION on the deploy command to specify region to be deployed.注意:这也可以通过将 function 部署到距离您的 Amazon RDS 数据库最近的位置来缓解,您可以查看此链接以了解哪些位置可用于 Cloud Functions,您可以在部署时使用--region=REGION命令指定要部署的区域。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM