Nodejs是不是会阻塞?

霸气全开
  • 103

express+mongoose做的。单台1核1g内存的node服务器。 我有个请求,去数据库查询耗时大概700ms左右,因为是聚合查询,而且数据量不小。这样子的一个请求,是不是会很严重的影响并发,我测试了下,几百的并发感觉有单撑不住。mongo那里cpu占用直接100%。访问一下就会很卡很慢,像是阻塞了。 为什么说是阻塞了。因为我又开了台node一模一样,连接同一个mongo数据库,访问完全没有问题,数据库查询也没问题。。。就想问这样子的请求是不是已经阻塞了node?

回复
阅读 4.8k
4 个回答
✓ 已被采纳

node.js中同时存在同步代码和异步代码,你看node.js的API,带Sync后缀的函数都是同步函数,一般的IO操作都是异步函数。node.js的异步是通过在libuv层的线程中处理完之后,然后通过事件轮询通知js,libuv在进行处理的时候不抢占js的处理时间,所以说是异步的。对于js异步的理解可以参见我的博文:http://blog.whyun.com/posts/js/
然后就是堵塞的问题,虽然是异步处理的,如果这个异步处理的耗时很长,那么在时间轮询中就肯定不会立即将处理结果交给js,而是要等libuv处理完成之后才能得到处理结果。js那端拿不到处理结果,那么就没法给浏览器返回数据,所以看上去请求就被堵住了。
这里libuv之所以处理的时候耗时长,我认为是数据库本身的问题,你这里直接使用聚合操作,本身就是一个耗时操作,不推荐在线上环境使用。另外我推荐你看一下索引的设置,查询的时候是否用上索引了。

卡在数据库了。

mongo的cpu占用高,表示任务繁忙,它正在拼命干活
单次查询700ms,当几百个查询同时提交给mongo时,mongo一下子处理不过来,会造成未处理的请求堆积、排队,

单次请求消耗时间 = 等待时间 + 处理时间,
因为单次处理时间为700ms, 所以等待时间越长, 请求消耗的时间越长, 就会感觉访问卡死了。

建议:
1.cache
a.可以加cache,缓存查询结果,减轻数据库压力
b.若加不了cache,考虑给mongo读扩展, 人多好办事
c.请优化代码、索引
2.客户(网页)端
a.使用加载动画, 比一动不动卡在那儿体验好

首先,node是单进程单线程的,所以肯定是可能阻塞的。然后,大部分学node的都应该懂一句话,“阻塞的是你的代码”,指的是你的同步代码会导致阻塞,比如死循环。数据库都是异步的,node不会阻塞住,慢的是数据库而已。不懂说明白没有。。。

1)任何代码写的程序都有可能被阻塞的,它也有吃饱撑不住的时候,每台机器的计算能力是有限的
2)nodejs解决前端客户请求的无阻塞性,也就是在机器连接能力允许的情况下,nodejs能尽可能多的接收前端的连接请求
3)看你的问题的描述,阻塞发生在数据库查询这个过程,这个过程的缓慢导致前端请求迟迟拿不到数据,直观的结果就是页面响应慢没反应

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏