【问题标题】:How to manage typeORM connection of Aurora Serverless data api inside Lambda using Serverless Framework如何使用无服务器框架在 Lambda 中管理 Aurora Serverless 数据 API 的 typeORM 连接
【发布时间】:2020-11-07 02:05:48
【问题描述】:

我正在使用:

我正在像 github 中描述的那样连接到数据库,

const connection = await createConnection({
      type: 'aurora-data-api-pg',
      database: 'test-db',
      secretArn: 'arn:aws:secretsmanager:eu-west-1:537011205135:secret:xxxxxx/xxxxxx/xxxxxx',
      resourceArn: 'arn:aws:rds:eu-west-1:xxxxx:xxxxxx:xxxxxx',
      region: 'eu-west-1'
    })

这就是我在 Lambda 函数中使用它的方式

export const testConfiguration: APIGatewayProxyHandler = async (event, _context) => {
  let response;
  try {
    const connectionOptions: ConnectionOptions = await getConnectionOptions();
    const connection = await createConnection({
      ...connectionOptions,
      entities,
    });
    const userRepository = connection.getRepository(User);
    const users = await userRepository.find();

    response = {
      statusCode: 200,
      body: JSON.stringify({ users }),
    };
  } catch (e) {
    response = {
      statusCode: 500,
      body: JSON.stringify({ error: 'server side error' }),
    };
  }
  return response;
};

当我第一次执行时,它运行良好。

但是第二次和下一次我得到一个错误

AlreadyHasActiveConnectionError: Cannot create a new connection named "default", because connection with such name already exist and it now has an active connection session.

那么,管理此连接的正确方法是什么? 是否应该以某种方式重复使用?

我找到了一些简单 RDS 的解决方案,但 Aurora Serverless 数据 API 的全部意义在于您不必管理连接

【问题讨论】:

  • 您确定问题与 Aurora 相关,而不与 Lambda 相关吗?在我看来,冷启动后连接保持打开状态,并且由于您不存储连接,因此每次连续调用 createConnection 都会尝试创建一个具有相同名称的新 TypeORM 连接,因此失败。

标签: aws-lambda serverless-framework typeorm aws-aurora-serverless


【解决方案1】:

当您尝试建立连接时,您需要检查是否已经存在可以使用的连接。这是我用来处理连接的Database 类

export default class Database {
  private connectionManager: ConnectionManager;

  constructor() {
    this.connectionManager = getConnectionManager();
  }

  async getConnection(): Promise<Connection> {
    const CONNECTION_NAME = 'default';

    let connection: Connection;

    if (this.connectionManager.has(CONNECTION_NAME)) {
      logMessage(`Database.getConnection()-using existing connection::: ${CONNECTION_NAME}`);
      connection = await this.connectionManager.get(CONNECTION_NAME);

      if (!connection.isConnected) {
        connection = await connection.connect();
      }
    } else {
      logMessage('Database.getConnection()-creating connection ...');
      logMessage(`DB host::: ${process.env.DB_HOST}`);

      const connectionOptions: ConnectionOptions = {
        name: CONNECTION_NAME,
        type: 'postgres',
        port: 5432,
        logger: 'advanced-console',
        logging: ['error'],
        host: process.env.DB_HOST,
        username: process.env.DB_USERNAME,
        database: process.env.DB_DATABASE,
        password: process.env.DB_PASSWORD,
        namingStrategy: new SnakeNamingStrategy(),
        entities: Object.keys(entities).map((module) => entities[module]),
      };

      connection = await createConnection(connectionOptions);
    }

    return connection;
  }
}

【讨论】:

    猜你喜欢
    • 2022-06-24
    • 2017-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-13
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    相关资源
    最近更新 更多