从单独的进程调用client.query
在这里不会给您带来真正的好处,因为向服务器发送查询已经是node-pg中的异步操作。然而,真正的问题是你的回调函数执行时间太长。该回调在主事件循环中同步运行,并阻止其他操作,所以将其设为非阻塞是一个好主意。
选项1:派生一个子进程
创建一个新的进程每次执行回调时间是没有好主意,因为每个Node.js的进程需要它自己的环境,这是建立耗时。相反,在服务器启动时创建多个服务器进程并让它们同时处理请求会更好。
选项2:使用Node.js的集群
幸运的Node.js提供cluster
接口来实现正是这一点。集群使您能够处理来自一个主进程的多个工作进程。它甚至支持连接池,所以你可以简单地在每个子进程中创建一个HTTP服务器,并且传入的请求将自动分配给它们(node-pg也支持池化)。
群集解决方案也很好,因为您不必为此更改很多代码。只需编写主进程代码并以工作人员身份启动现有代码即可。
official documentation on Node.js clusters解释所有方面,如果集群非常好,所以我不会在这里详细说明。只是一个可能的主码一个简单的例子:
var cluster = require("cluster");
var os = require("os");
var http = require("http");
if (cluster.isMaster)
master();
else
worker();
function master() {
console.info("MASTER "+process.pid+" starting workers");
//Create a worker for each CPU core
var numWorkers = os.cpus().length;
for (var i = 0; i < numWorkers; i++)
cluster.fork();
}
function worker() {
//Put your existing code here
console.info("WORKER "+process.pid+" starting http server");
var httpd = http.createServer();
//...
}
选项3:拆分结果的处理
我认为回调函数的执行时间较长的原因是,你必须处理很多结果行,并且没有机会以更快的方式处理结果。
在这种情况下,使用process.nextTick()
将处理分成几个块也是一个好主意。块将在多个事件循环帧中同步运行,但其他操作(如事件处理程序)可以在这些块之间执行。这里有一个粗略的(和未经测试)scetch的代码可能看起来怎么样:
function(err, result) {
var s, i;
s = 0;
processChunk();
// process 100 rows in one frame
function processChunk() {
i = s;
s += 100;
while (i<result.rows.length && i<s) {
//do some stuff with result.rows[i]
i++;
}
if (i<result.rows.length)
process.nextTick(processChunk);
else
//go on (send the response)
}
}
我不是100%肯定,但我认为节点-PG提供了一些办法不接收查询结果作为一个整体,但分成几块。这将简化代码很多,所以它可能是一个想法,寻找到那个方向......
最终结论
如果有新的我会在第一时间和选项3使用选项2另外,请求仍然需要等待太久。
嗯,所以回调/ /做一些东西会阻止主要过程? – OliverJ90
只要'do stuff'部分不是异步的,那么就会阻塞。事件循环只是对'while(){switch(){}}'循环(换句话说,一个状态机)的花哨抽象 – slebetman
啊,似乎我错误地认为从最初的client.query回调是异步的。 – OliverJ90