以 express.js
的 serve-statc
的 send
依赖模块为例,本想学习一下,却完全没有看到处理 EMFILE
异常的逻辑。
是 stream
体系不会触发这一限制,还是说这一逻辑被底层引擎忽略了,需要业务逻辑框架自行处理?
即便是交由业务逻辑自行处理也很有问题,因为系统必须为静态服务限定一定的资源使用范围,不能说达到上限了抛出异常了事,那其他通常不会出现该问题的逻辑全都会受到株连、“被(静态文件服务器)用光”所有可用的文件描述符。由于是操作系统的限制,所以即便和 nginx
配合使用,自然会对业务逻辑进程造成这种影响。有什么应对的思路?
再者,并发的多个请求针对同一个文件 path
时,fs.createReadStream
会被多次调用,有可能复用吗?如果不能复用,同一 path
的多个 readStream
会累加系统最大打开的文件描述符的占用吗?
另外,如果这一异常发生,是在 fs.createReadStream
函数执行时抛出,还是在 readStream.on("error")
监听中异步抛出?这个异常不太好模拟测试,所以请教一下有经验的大神,谢谢!
从侧面回答一下第二个问题吧,希望不要被踩。
如果是静态文件服务器,为了提高性能建议搞一下缓存处理,也就是说第一次请求的时候,内存的缓存中没有数据,则把文件读到缓存中,下一次请求来的时候,缓存中有数据,则直接走缓存,不要每次都搞文件 I/O,虽然 node.js 支持文件异步 I/O,但是异步操作文件也比内存效率低一些。附上简单的代码,如下:
关于第三个问题,如果异常发生,readStream.on('error')是捕获异常的,不会在这里抛出异常的。关于测试,可以搞一下压力测试,在服务器上多放一些大文件,用 node.js 写个客户端发出 HTTP 请求的脚本,并发请求这些大文件,看看服务程序会不会崩溃。