使用 "node postgres" 的 Nodejs 应用程序在 GKE 中每 60 分钟有一个 "Connection terminated unexpectedly"
Nodejs application using "node postgres" having a "Connection terminated unexpectedly" every 60min in GKE
我有多个 运行 使用 Node.js 和 pg (node-postgres) 的应用程序。
我遇到的问题是每个应用每小时都会收到错误“连接意外终止”。这是错误:
> node ./dist/app.js
App Started
events.js:174
throw er; // Unhandled 'error' event
^
Error: Connection terminated unexpectedly
at Connection.con.once (/app/node_modules/pg/lib/client.js:255:9)
at Object.onceWrapper (events.js:286:20)
at Connection.emit (events.js:198:13)
at Socket.<anonymous> (/app/node_modules/pg/lib/connection.js:139:10)
at Socket.emit (events.js:203:15)
at endReadableNT (_stream_readable.js:1145:12)
at process._tickCallback (internal/process/next_tick.js:63:19)
Emitted 'error' event at:
at connectedErrorHandler (/app/node_modules/pg/lib/client.js:202:10)
at Connection.con.once (/app/node_modules/pg/lib/client.js:272:9)
at Object.onceWrapper (events.js:286:20)
[... lines matching original stack trace ...]
at process._tickCallback (internal/process/next_tick.js:63:19)
以下是我如何将我的客户端连接到数据库:
Database.ts:
import { Client, QueryResult } from 'pg';
export default class DatabaseModule {
private client: Client;
constructor() {
this.client = new Client({
connectionString: process.env.DATABASE_URL
});
}
public init(): Promise<any> {
return this.client.connect();
}
}
app.ts:
Promise.all([
express.init(),
database.init()
])
.then(() => {
console.log("App Started");
[load routes...];
})
.catch((error) => {
console.error(error);
process.exit(1);
});
在本地一切正常,但在生产环境中不正常。
在生产环境中,我们运行将每个应用程序作为 Google Kubernetes Engine 中的微服务。 K8s 中是否有任何配置可能导致每小时连接丢失? (即使Client空闲或不空闲,也会出现这个错误)
NAME READY STATUS RESTARTS AGE
my-service-57c9f99767-wnm47 2/2 Running 96 4d
如您所见,我的应用程序有 96 次重启:4 天 * 24 小时 = 96 => 每小时都会出现导致 pod 崩溃的错误。
我们正在使用由 Google Cloud SQL 托管的 postgreSQL 服务器,K8s 中的每个应用程序都可以通过本地地址访问它。
编辑:
我刚刚在 Google Cloud SQL 文档中找到了这个:
WebSockets are always available to your application without any additional setup. Once a WebSockets connection is established, it will time out after one hour.
所以错误是由于使用 pg.Client 与 SQL 服务器的持久连接而产生的。我将尝试使用 pg.Pool()。
这是为什么我应该使用池而不是客户端的解释:
我发现了问题:
在 Google 云 SQL 文档中:WebSockets are always available to your application without any additional setup. Once a WebSockets connection is established, it will time out after one hour.
错误是由 pg.Client() 的使用产生的,因为我与我的数据库建立了持久连接,这是一种不好的做法。客户端应连接到数据库,然后在完成查询后结束连接。
我将使用 pg.Pool(),因为它会生成客户端并且更适合多个请求。
客户生成后,我只好释放我所有的客户。
我删除了 database.init() 并修改了 database.query() 函数,如下所示:
public query(command: string, args?: Array<any>): Promise<QueryResult> {
if (args === undefined)
args = [];
return this.pool.connect()
.then((client: Client) => {
return this.queryClient(client, command, args)
})
.then((result: QueryResult) => {
return result;
})
.catch((error) => {
throw error;
});
}
private queryClient(client: Client, command: string, args?: Array<any>): Promise<QueryResult> {
return client.query(command, args)
.then((result: QueryResult) => {
client.release();
return result;
}).catch((error) => {
client.release();
throw error;
})
}
我有多个 运行 使用 Node.js 和 pg (node-postgres) 的应用程序。
我遇到的问题是每个应用每小时都会收到错误“连接意外终止”。这是错误:
> node ./dist/app.js
App Started
events.js:174
throw er; // Unhandled 'error' event
^
Error: Connection terminated unexpectedly
at Connection.con.once (/app/node_modules/pg/lib/client.js:255:9)
at Object.onceWrapper (events.js:286:20)
at Connection.emit (events.js:198:13)
at Socket.<anonymous> (/app/node_modules/pg/lib/connection.js:139:10)
at Socket.emit (events.js:203:15)
at endReadableNT (_stream_readable.js:1145:12)
at process._tickCallback (internal/process/next_tick.js:63:19)
Emitted 'error' event at:
at connectedErrorHandler (/app/node_modules/pg/lib/client.js:202:10)
at Connection.con.once (/app/node_modules/pg/lib/client.js:272:9)
at Object.onceWrapper (events.js:286:20)
[... lines matching original stack trace ...]
at process._tickCallback (internal/process/next_tick.js:63:19)
以下是我如何将我的客户端连接到数据库:
Database.ts:
import { Client, QueryResult } from 'pg';
export default class DatabaseModule {
private client: Client;
constructor() {
this.client = new Client({
connectionString: process.env.DATABASE_URL
});
}
public init(): Promise<any> {
return this.client.connect();
}
}
app.ts:
Promise.all([
express.init(),
database.init()
])
.then(() => {
console.log("App Started");
[load routes...];
})
.catch((error) => {
console.error(error);
process.exit(1);
});
在本地一切正常,但在生产环境中不正常。
在生产环境中,我们运行将每个应用程序作为 Google Kubernetes Engine 中的微服务。 K8s 中是否有任何配置可能导致每小时连接丢失? (即使Client空闲或不空闲,也会出现这个错误)
NAME READY STATUS RESTARTS AGE
my-service-57c9f99767-wnm47 2/2 Running 96 4d
如您所见,我的应用程序有 96 次重启:4 天 * 24 小时 = 96 => 每小时都会出现导致 pod 崩溃的错误。
我们正在使用由 Google Cloud SQL 托管的 postgreSQL 服务器,K8s 中的每个应用程序都可以通过本地地址访问它。
编辑:
我刚刚在 Google Cloud SQL 文档中找到了这个:
WebSockets are always available to your application without any additional setup. Once a WebSockets connection is established, it will time out after one hour.
所以错误是由于使用 pg.Client 与 SQL 服务器的持久连接而产生的。我将尝试使用 pg.Pool()。
这是为什么我应该使用池而不是客户端的解释:
我发现了问题:
在 Google 云 SQL 文档中:WebSockets are always available to your application without any additional setup. Once a WebSockets connection is established, it will time out after one hour.
错误是由 pg.Client() 的使用产生的,因为我与我的数据库建立了持久连接,这是一种不好的做法。客户端应连接到数据库,然后在完成查询后结束连接。
我将使用 pg.Pool(),因为它会生成客户端并且更适合多个请求。 客户生成后,我只好释放我所有的客户。
我删除了 database.init() 并修改了 database.query() 函数,如下所示:
public query(command: string, args?: Array<any>): Promise<QueryResult> {
if (args === undefined)
args = [];
return this.pool.connect()
.then((client: Client) => {
return this.queryClient(client, command, args)
})
.then((result: QueryResult) => {
return result;
})
.catch((error) => {
throw error;
});
}
private queryClient(client: Client, command: string, args?: Array<any>): Promise<QueryResult> {
return client.query(command, args)
.then((result: QueryResult) => {
client.release();
return result;
}).catch((error) => {
client.release();
throw error;
})
}