0

我一直在尝试使用该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错误。

4

2 回答 2

9

Node.js 和 Cloud SQL的Cloud Functions 文档(向下滚动到 PostgreSQL)包含有关构建连接字符串和凭据所需的其他配置的适用信息。

为您的应用准备好之后,您需要将 Cloud SQL 实例添加到您的 Cloud Run 服务,然后它才能使用该连接字符串访问数据库。

这里直接从文档中复制代码示例,使用 Cloud Run max1 的配置可能跟不上其他并发设置。

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.
};
于 2019-09-27T15:48:07.287 回答
1

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

Unix 域套接字是用于进程间通信的套接字。如果您可以选择 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 实例添加到您的 Run 部署中(按照以下步骤操作)。
  3. 确保运行您的代码的服务帐户具有Cloud SQL ClientIAM 权限(这是通过第 2 步为默认服务帐户完成的)
  4. 配置您的应用程序以连接/cloudsql/INSTANCE_CONNECTION_NAME
于 2019-09-27T21:39:52.383 回答