Nodejs是不是会阻塞?


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

node.js mongoose

BBQ222 10 years, 2 months ago

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

zycpig answered 10 years, 2 months ago

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

cocoo answered 10 years, 2 months ago

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

sdza100 answered 10 years, 2 months ago

Your Answer