关于Koa2.0框架中间件数量过多后存在的栈溢出隐患
发布于 4 天前 作者 hyj1991 437 次浏览 来自 问答

今天突然想起来,Koa2.0这种Promise.resolve嵌套的方式类似递归,不知道在中间件数量比较庞大的时候会不会造成栈溢出,虽然比较罕见,测试代码如下:

'use strict';
const compose = require('koa-compose');
let middlewares = [];

for (let i = 0; i < 10000; i++) {
	middlewares.push(function (ctx, next) {
    	return next();
	});
}
compose(middlewares)({}).then(data=>console.log(data)).catch(err=>console.error(err));

结果

//在compose的return dispatch(i+1)处打印了 console.log(i+1)
4826
4827
4828
4829
[RangeError: Maximum call stack size exceeded]

在运行到5000左右的时候居然真的栈溢出了… 好吧,虽然一个项目使用到5k的中间件相当罕见,但是说明还是有这个隐患点的…尤其是如果在中间件里面又进行了一些递归操作的话

14 回复

在koa2.0下,如果编写的中间件使用co.wrap或者koa-convert,实测满足栈溢出的中间件数量下限下降很快,co.wrap大概1200个就会栈溢出,而使用koa-convert,在800个左右的中间件就会栈溢出… 这样的话,考虑到自己编写的业务逻辑里面的额函数调用栈,中间件数量还要进一步降低 有没有人遇到过这样的问题呢,还是我测验的时候逻辑有问题 按理来说,一个不错的web框架不应该有这种问题才是…

我没见过中间件嵌套特别多的,koa的benchmark最多才做到50个。。。。。兄弟,你这是要闹哪样?

中间件有事没事都过一遍这也不是一种好的设计

@i5ting 我也觉得不大可能有这么多中间件,但是这样一来,总感觉人为的有了一些限制 而且就像三楼的朋友说的那样,中间件数量一多,所有的request都要过一遍,性能上也会降低;我在想有没有办法实现按需加载中间件的机制 这两天做view层的npm组件化,有点忙,今天才想起来上下CNODE社区,所以这么久才回复,哈哈

@yakczh 确实,所以我空闲的时候也在想,能不能实现中间件的按需加载机制

@hyj1991 新版的compose又有大大的性能提升,本社区的fundon同学使用es6的迭代器写的,很快会合并.

@i5ting 期待源码,学习下 koa1.0和koa2.0的compose我都看过了,其实相比较而言,1.x的compose就像黑魔法,第一次看到是一种惊艳的感觉 2.x的compose就平淡了很多,当然相对来说,基于Promise的compose泛用性也好一些 期待新的compose

这是 V8层面的stackoverflow的检查,尝试调整系统 stack 大小,MacOSX 默认8192, ulimit -s 16384。

我现在用的compose 是 3.1.0的 新版的compose是哪个版本?

@i5ting es6 的迭代其方案 有问题,高兴早了

@fundon 能大致说下实现思路吗,了解下,哈哈

回到顶部