我正在使用Node.js来构建服务器端RESTApi。当我自己测试时,Node工作正常。但是当它真的存在时它仍然可能面临溢出问题。当有很多请求时,假设有5个以上的child_process(spawn)同时工作,每个进程都需要更长的时间,基本上会减慢一切。
我的想法是检查当前进程是否低于某个限制(例如,一次限制为3个进程),如果超出限制,我将请求保存到数组中,并且每当当前进程低于限制,我使用.shift()弹出数组中最旧的一个并处理它。
然而,当涉及到Promises时,由于我不知道我们是否可以将Promise存储到阵列中,或者我是否应该让这个过程停顿几秒钟而变得困难。我认为这是一个好主意。
如果您希望将来承诺并将承诺退还给客户,那么正常的方法是什么?
对不起,如果我没有说明这一点。以下是我的疑惑摘要: 我们能否保留未来使用的承诺? 我们把它们保存在阵列中吗? 3.我应该使用其他方法来保持承诺,例如,使用sleep()或只是一个while循环来等待这个过程继续进行?
谢谢!
答案 0 :(得分:2)
说有超过5个child_process(spawn)同时工作,每个进程花费更长的时间,基本上减慢了一切。
在实际部署中 - 您不会以这种方式处理子任务的CPU密集型任务 - 您将使用理智的并发数据结构(如mqtt或数据库上的队列)并将工作分发给您部署的工作人员然后将其发送回服务器。
原因是服务器总是可以停机 - 而且你想要防止部分工作。
我的想法是检查当前进程是否低于某个限制(例如,一次限制为3个进程),如果超出限制,我将请求保存到数组中,并且每当当前进程低于限制,我使用.shift()弹出数组中最旧的一个并处理它。
以下代码执行此操作,我请求您阅读第一点而不在生产中使用该代码,而是在部署时限制该代码(例如,如果您使用AWS将规模限制为3个实例):
// lifted from my bluebird-api project
function throttle(fn, concurrency = 20, Promise) {
// create an array of workers as resolved promises
const workers = Array(concurrency).fill(Promise.resolve());
const work = []; // pending work
return function (...args) {
// when there is work, pull the next worker
const worker = workers.pop();
if (worker === undefined) { // if there is no pending worker
let resolve, reject;
// store the promise for the result
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
// and add it to the queue
work.unshift({ args, resolve, reject, promise });
return promise;
}
// after the worker is ready, call the function
worker = worker.then(() => (fn(...args), null));
worker.then(function pump() {
if (work.length) { // after you're ready
const {resolve, reject, args} = work.pop();
// continue draining the queue
worker = worker.then(() => fn(...args)).then(resolve, reject).then(pump);
} else { // or declare ready
workers.push(worker);
}
return null;
});
return worker;
}
}
代码从仍为WIP的bluebird-api解除。
如果您希望持有承诺并在将来向客户承诺承诺,那么正常的方法是什么?
是的,它完全是受支持的案例 - 并且它不会泄漏内存并且是安全的(在现代承诺实施中)。虽然再次 - 这是一个XY问题 - 您不应该在节点服务器上以这种方式分配工作。
当您实现正确的解决方案(排队和卸载到不同的服务)时,您可以创建一个promises队列,您可以在其中返回一个promise并在队列准备好后再解析它。
答案 1 :(得分:1)
- 我们能否保留未来使用的承诺? 2.我们将它们保存在数组中吗?
你可以在一个数组中存储一个Promise,这是承诺的一部分,它们在需要之前不需要进行评估。
- 我应该使用其他方法来保持承诺,例如,使用sleep()或只是一个while循环来等待这个过程继续进行?
使用睡眠没有错。不要循环效率低下。
修改的
@Bergi在评论中说,即使在承诺sleep
中也不应该使用。