我正在使用Node.js构建服务器端RESTApi.当我自己测试时,Node工作正常.但是,当它确实存在时,仍然可能会遇到溢出问题.当有很多请求时,例如说有5个以上的child_process(spawn)同时工作,则每个进程花费的时间更长,基本上会减慢一切.
我的想法是检查当前进程是否低于某个限制(例如一次限制为3个进程),如果超过该限制,则将请求保存到数组中,并且每当当前进程低于该限制时,我使用.shift()来弹出数组中最旧的一个并进行处理.
但是,当涉及到Promises时,将变得很困难,因为我不知道我们是否可以将Promise存储到数组中,或者我是否应该让过程暂停几秒钟,我认为这不是一个好主意.
如果您要保留承诺并在将来将承诺退还给客户,通常的方法是什么?
抱歉,如果我没有说清楚.以下是我的疑问摘要:
1.我们可以保留将来的诺言吗?
2.我们是否将它们保存在数组中?
3.我是否应该使用其他方法来保持承诺,例如使用sleep()还是仅使用while循环来等待该过程进行?
谢谢!
解决方法:
say there are more than 5 child_process (spawn) working at the same time, each process is taking longer time, basically slow down everything.
在实际部署中-您不会以这种方式处理带有子任务的cpu密集型任务-您将使用合理的并发数据结构(例如mqtt或数据库上的队列)并将工作分配给您部署的工作人员,然后由工作人员将其发送回到服务器.
原因是服务器始终会停机-并且您要防止部分工作.
My idea is to check if the current process is below a certain limit (like, limit to 3 processes at a time), if it exceed the limit, I save the requests into an array, and whenever the current processes is below the limit, I use .shift() to pop the oldest one in the array and process it.
这是执行此操作的代码,请您阅读第一点,而不在生产环境中使用该代码,而是在部署时将其限制(例如,如果您使用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提升.
What is the normal way if you want to hold a promise and return the promise to client in future?
是的,这完全是受支持的情况-并且不会泄漏内存并且很安全(在现代promise实现中).尽管再次出现-这是一个XY问题-您不应以这种方式在Node服务器上分发工作.
当您实现正确的解决方案(排队并分流到不同的服务)时,您可以创建一个Promise队列,在其中您返回一个Promise,并在队列准备就绪时稍后对其进行解析.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。