无法使用node-postgres连接到Cloud SQL

时间:2019-09-27 07:12:45

标签: postgresql database-connection google-cloud-sql google-cloud-run cloud-sql-proxy

我一直在尝试使用 pg 模块连接到我的Cloud SQL实例,但是到目前为止还没有成功。

我在网上浏览了很多东西,但是对这个话题不太了解。我还想在某个时候在Cloud Run上部署Express应用程序,并将其连接到Cloud SQL实例,但是我不知道该怎么做。

以下是我不了解的事情清单,并希望对此做一个简要说明:

  1. 什么是Unix套接字连接?为什么我应该在普通连接上使用它们?
  2. 什么是Cloud SQL代理?我需要使用它吗?如果是这样,为什么?
  3. 我需要做一些额外的工作才能从Cloud Run连接到我的Cloud SQL实例吗?

这里是我尝试使用pg.Client对象的所有连接对象和连接字符串:

  1. 第一个连接字符串:postgresql+psycopg2://postgres:password@/cloudsql/myapp:us-central1:mydb?host=/var/lib/postgresql
  2. 第二个连接字符串:postgresql://postgres:password@hostip:5432/myapp:us-central1:mydb
  3. 第三连接字符串:postgresql://postgres:password@hostip:5432/sarcdb
  4. 连接对象:{ host: "/cloudsql/myapp:us-central1:mydb", username: "postgres", password: "password", database: "mydb" }

所有这些给我一个Connection terminated unexpectedly错误。

2 个答案:

答案 0 :(得分:3)

Cloud Functions documentation for Node.js & Cloud SQL(向下滚动到PostgreSQL)具有有关结构化连接字符串和凭据所需的其他配置的适用信息。

在您的应用程序安装好之后,您将需要add the Cloud SQL instance to your Cloud Run service才能使用该连接字符串访问数据库。

这里直接从文档中复制代码示例,使用Cloud Run的max配置为1可能无法与其他并发设置保持同步。

const pg = require('pg');

/**
 * TODO(developer): specify SQL connection details
 */
const connectionName =
  process.env.INSTANCE_CONNECTION_NAME || '<YOUR INSTANCE CONNECTION NAME>';
const dbUser = process.env.SQL_USER || '<YOUR DB USER>';
const dbPassword = process.env.SQL_PASSWORD || '<YOUR DB PASSWORD>';
const dbName = process.env.SQL_NAME || '<YOUR DB NAME>';

const pgConfig = {
  max: 1,
  user: dbUser,
  password: dbPassword,
  database: dbName,
};

if (process.env.NODE_ENV === 'production') {
  pgConfig.host = `/cloudsql/${connectionName}`;
}

// Connection pools reuse connections between invocations,
// and handle dropped or expired connections automatically.
let pgPool;

exports.postgresDemo = (req, res) => {
  // Initialize the pool lazily, in case SQL access isn't needed for this
  // GCF instance. Doing so minimizes the number of active SQL connections,
  // which helps keep your GCF instances under SQL connection limits.
  if (!pgPool) {
    pgPool = new pg.Pool(pgConfig);
  }

  pgPool.query('SELECT NOW() as now', (err, results) => {
    if (err) {
      console.error(err);
      res.status(500).send(err);
    } else {
      res.send(JSON.stringify(results));
    }
  });

  // Close any SQL resources that were declared inside this function.
  // Keep any declared in global scope (e.g. mysqlPool) for later reuse.
};

答案 1 :(得分:0)

  

什么是Unix套接字连接,为什么我应该在普通连接上使用它们?

Unix domain socket是用于进程间通信的套接字。如果您可以选择在TCP连接和Unix域套接字之间进行通信,则Unix域套接字可能会更快。

  

什么是Cloud SQL代理?我需要使用它吗?如果是这样,为什么?

Cloud SQL代理允许您使用服务帐户的IAM权限对连接进行身份验证以连接到数据库。

由于Cloud SQL是云数据库,因此(默认情况下)它需要某种形式的身份验证来帮助确保其安全性。与自我管理的SSL证书或列入白名单的IP地址相比,代理是一种更安全的连接方法。

  

我需要做一些额外的工作才能从Cloud Run连接到我的Cloud SQL实例吗?

Cloud Run会为您运行代理,但是您需要执行以下操作:

  1. 启用Cloud SQL Admin API
  2. 将Cloud SQL实例添加到您的运行部署(follow these steps)。
  3. 确保运行您的代码的服务帐户具有Cloud SQL Client IAM权限(这是在步骤2中针对默认服务帐户完成的操作)
  4. 配置您的应用程序以与/cloudsql/INSTANCE_CONNECTION_NAME进行连接