从头说起,最近服务器硬盘空间开始紧张,主要是用户上传文件不断增加导致的,于是前天着手解决
我们用的青云,很简单,新建块硬盘挂上,把上传目录迁移过去,然后ln
一下,搞定
然后就悲剧了
昨天晚上无意间发现大量文件404了,赶紧查
第一反应是挂载有问题,排除,权限问题,排除,log也没发现对应错误(其实基本没什么log…)
没辙了只能反复试错,然后确定问题肯定在ln
上,进而确定是跨盘ln
造成的,甚至开始怀疑是CentOS的bug…
搞了几个小时没找到解决方案,决定放弃,准备调整系统改为把上传目录指定到新磁盘上(幸亏没做做了也没用)
然后冷静了一会,决定去翻上传代码,上传用的是 flow.js,服务端就直接用了它的示例代码,由于比较复杂一直不想碰,翻了一会看到了这行: https://github.com/flowjs/flow.js/blob/master/samples/Node.js/flow-node.js#L112
fs.rename(files[$.fileParameterName].path, chunkFilename, function() {
//...
});
直觉告诉我就是它了,一查果然:https://github.com/joyent/node/issues/2703(看下底下那一堆ref都是栽在这的) 擦,fs模块竟然用rename来处理move,而且还不符合move的语义,然后示例代码压根就没考虑处理rename错误,然后万年callback坑又把异常给吃掉了… 找到问题就等于解决了,后面就不说了
教训:
- Callback的的确确是Hell
- 错误处理不当坑死人,做大项目堪忧
- log多多益善
- 拿来主义害死人,在Node里用第三方代码一定慎之又慎