【发布时间】:2021-01-24 17:01:22
【问题描述】:
第一次使用“免费层”设置 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 连接池中的连接?
【问题讨论】:
标签: javascript postgresql heroku knex.js koa2