Heroku Postgres连接增加,无需重用

问题描述

首次使用“免费套餐”设置Heroku的postgres服务。我使用heroku来托管带有pg数据库的koa服务器。服务器通过knexjs与数据库进行通信。我不确定我是否使用了不正确的knexjs,因为每次我运行查询时,它都会创建一个新连接,如通过Heroku的仪表板看到的那样,最终会耗尽连接。另外,我注意到它们是主要消耗我连接的内部IP(即10.1 ...)。如果我杀死了它们,那么我的连接将降为0。我的knex查询如下:

出于缓存目的,我在每个连接上启动了一个类(仅在同一客户端请求期间运行多个查询时才有用)。

import knexDefault from "knex";
import { development,production } from "../ConfigKnex";
import { ENVTRANS } from "./Consts";

const { ISDEV } = ENVTRANS;
export class KnexCache(){
  knex = knexDefault(ISDEV ? development : production);
  transaction = this.knex.transaction.bind(this.knex);
  constructor(private cache: Map<string,any> = new Map()) {}
  private CacheIt(action: ActionTypes,table: string,props: any,fn: any) {
        let tm = this.cache.get(table);
        if (!tm) {
            tm = new Map<string,any>();
            this.cache.set(table,tm);
        }
        const key = `${action}|${JSON.stringify(props)}`;
        let res = tm.get(key);
        if (res) return res;
        res = fn();
        tm.set(key,res);
        return res;
    }
  async SelectAsync<T>(
        table: string,where: Partial<T>,db = this.knex,): Promise<T[]> {
        return this.CacheIt("SelectAsync",table,{ where },() =>
            db(table).where(where).select(),);
    }
  ...
}

我使用GraphQL(因此称为ApolloServer)在每个连接上创建一个新的KnexCache。

const server = new ApolloServer({
    typeDefs,resolvers,// schemaDirectives,debug: ISDEV,tracing: ISDEV,playground: {
        settings: {
            "request.credentials": "include",},context: async (context) => {
        context.k = new KnexCache();
        return context as Context;
    },});

然后在我的解析器中调用

export const resolvers = {
  Query: {
    GetData: async (p,a,c,i) => {
      const { k } = c;
      return k.SelectAsync<TABLETYPE>("TABLENAME",{ id: "someId" });
    },};

一切正常,但是我是否以不正确的方式使用knex来保持连接活动和/或防止连接重用?如何“修复”代码以正确重用knex的连接池中的连接?

解决方法

我知道了。由于我为每个连接创建一个新类,因此将为每个访问者建立一个新的knex连接。我尝试将knex属性设为静态,但显然在javascript中,静态属性只能由静态方法访问...因此,我将knex属性移至类之外,并将其转换为export const