Nodejs的express框架中当前路由可能会阻塞主线程。
环境:是这样的,我用nodejs的express框架搭建了一个web服务器。
有一个路由:/download
1.路由中执行了一条SQL语句,这条语句并不复杂只需几百毫秒就执行完成了。
但是这条SQL查询出来的数据比较多,大概有3万来条。
2.SQL语句执行完后把返回的数据(JSON格式)利用路由返给前端页面,也就是下载这个SQL查询出来的数据。这里用插件把JSON转成了xlsx后再下载。
结果:
由于数据较多,从查询完到弹出下载框的时间很行。大概在20秒左右。
在这期间,其它路由是无法访问的,必需要等到这个路由返回完成。阻塞住了!
如果用setTimeout的方式延时res.send()是不影响其它路由的,也就是说并不是路由阻塞了主线程,而是这个JSON转二进制的过程阻塞了主线程。
我尝试过,如果不转二进制,只在循环里打印SQL的结果(console.log())同样是阻塞的,这不禁让我怀疑console.log是同步的???
问题:
1.console.log是同步的?
2.如果解决这种大量数据的导出呢?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
从描述看来阻塞是来自于服务器的复杂运算导致其他请求响应变慢了。对于REST来说API的数据请求过大就算服务端不卡死客户端也会相应超慢,单一数据过大会严重拖慢响应速度。比较妥善的办法是将API拆分分发数据,比如一次200条(根据你的数据模型复杂度来定),发送多次请求获得完整数据
nodejs是单线程吧.
console.log 当然是同步的,你难道以为 everything 都是异步吗。
大量数据的导出使用stream流的形式。
你所说的路由阻塞了,如果不同的路由是毫不相关的,凭什么一个会阻塞另一个,你代码写的有问题吧。
fork一个子进程去处理数据比较大的这部分工作应该会缓解一下主线程压力。