说说我对node的小见解
发布于 2年前 作者 xadillax 1030 次浏览

其实主要是对于异步的一个见解把。

很多人说node异步怎么怎么好,可以解决并发量大的问题。

的确,这是node吸引我的其中一个地方。

也许是我浅薄了,怎么也想不明白,不管三七二十一,全部都用异步,合适么?其中一个是打乱了代码本身的流程结构性。

异步固然好,但是对我来说,只需要在接受请求的时候,将其异步一下给回调函数即可,而在这个回调函数里面,我们完完全全可以直接用同步的方式来执行了。因为对于这个人来说,他的访问卡不卡已经影响不到别人了。而对于他自己来说,难道你异步了就能更快很多了?不也还是得执行完了,然后执行回调函数的时候那个人才能看到你返回给他的一些渲染数据?

所以我个人认为在接受请求的时候异步一下就够了。

以上完全为个人的浅薄见解,还希望各位大神帮忙解释一下一些微妙之处,比如各种异步。谢谢。

13 回复

最近也一直痴迷于Node.js,根据我的理解,node.js的异步并不能使客户端访问页面变得更快。 它能提供的好处是,可以使服务器的吞吐量变大,也就是说在同一时间内能接受的请求更多。如果原来有很多台服务器来处理大量的并发,用node.js后也许只需要一台或者几台就够了,节约了服务器的成本

像你所说的如果只是在接受请求的时候异步一下,然后就使用回调函数。回调函数也是在js的主线程里跑的,如果回调函数里有同步IO操作,那么主线程必然受阻,导致后边的请求都没有办法及时处理,还是没有能充分利用CPU

node是单线程。所以如果不想瓶颈出现,就是得尽量去异步。不然万一哪怕有0.5秒的卡住,那你的server服务能力就立即变成 2 resp/s。

照你这么说回调函数的回调函数难道就不是在主线程跑了?

@XadillaX 是在主线程里跑呀, 但一有耗时的IO操作,用异步的话,就不需要等待了,直接跳过执行后边的请求。等IO操作完成时,又会调用回调函数。

更正一下: 对于node.js还需要有一个正确地理解就是,node.js 是非I/O阻塞,而不是非cpu阻塞。 发现这个论坛不能原文更改。

看到你致力于mongodb等一些操作的同步化,就感觉没有理解node.js:) 其实要了解node.js还是要真正理解http和javascript。. 对于web服务端,我们都知道有Apache和Nginx。 我们也知道php和Apache是一对。 但我们更需要了解 CGI(Common Gateway Interface),php就是采用的fastcgi,fastcgi是多线程,通常一个服务器可以开多个线程,php每一次请求都会开一个服务器进程,每个线程内都是独立的,一个线程的崩溃就会影响到另外一个线程,无论如何你开的线程都是有限的,所以在高并发面前还是有所限制(指单台服务器)。 而Nginx公认为比Apache更快,Nginx就是采用的单线程模型,也就是所有的请求都是在一个线程里面。 我们回到node.js,node.js是单线程,这个线程是主线程,但os所有的服务又是独立的进程,例如I/O操作和数据库操作,node.js的主线程就是一个事件队列,当发生一个请求后,node.js只是在这个事件队列中注册一个事件,然后就不管了,具体这个事件的执行就交给了os(i/o,database),等os完成后,通过回调事制(node.js会轮询)再回到主线程的处理,这样就加加提高了并发能力,因为所有的处理都是在一个线程里(开一个线程需要太多额外的消耗)。 对于node.js还需要有一个正确地理解就是,node.js 是非I/O阻塞,而不是非cpu阻塞,也就你阻塞了cpu话,例如在node.js代码中第一个请求for(很大的循环)或while就会发现第二个请求会在第一个请求结束后才会执行(主线程阻塞了),这点非常重要(所以在node.js遇到时间长的运算,一定要做成分拆,做成回调的形式)。 那么node.js会出现cpu阻塞,是不是性能就会有问题呢?不是的,就象Nginx一样,因为对web而言运算是非常非常小的,一次I/O的操作的时候远大于你做10万次的for循环。 从根本去理解node.js的进程就能够找到node.js的应用场景。

昨天看到一篇@老赵 的文章, 觉得 Node 也是类似 http://www.ituring.com.cn/article/37181

我们知道,操作系统的最小调度单元是“线程”,要执行任何一段代码,都必须落实到“线程”上。可惜线程太重,资源占用太高,频繁创建销毁会带来比较严重的性能问题,于是又诞生出线程池之类的常见使用模式。也是类似的原因,“阻塞”一个线程往往不是一个好主意,因为线程虽然暂停了,但是它所占用的资源还在。线程的暂停和继续对于调度器都会带来压力,而且线程越多,调度时的开销便越大,这其中的平衡很难把握。

正因为如此,也有人提出并实现了fiber或coroutine这样的东西,所谓fiber便是一个比线程更小的代码执行单位,假如说“线程”是用来计算的“物理”资源,那么fiber就可以认为是计算的“逻辑”资源了。从理念上说,goroutine和WebWorker都是类似fiber或coroutine这样的概念(所以叫做goroutine):它们都是执行逻辑的计算单元,我们可以创建大量此类单元而不用担心占用过多资源,自有调度器来使用一个或多个线程来执行它们的逻辑。

这样就明白了嘛。

但是阻塞对于代码结构设计来说还是比较头疼的一件事。本来我只是想写一个在node下非常方便的框架而已。

@XadillaX 其实这回复,我是特意注册上来的回复的,因为对于代码,认真和努力是最最重要的。

更正一下,很重要 php每一次请求都会开一个服务器进程,每个线程内都是独立的,一个线程的崩溃不会影响到另外一个线程

@XadillaX 要知道IO的操作会比CPU慢上千万倍

一图胜千言,为什么要异步。答案是IO相比CPU慢太多了。让CPU不等待IO,提升CPU的利用率。

对于分布式应用,网络IO是很常见的操作。假想下一个页面的渲染要从网络中读10次数据。如果是同步的方式做,时间消耗是线性增长的。而异步达到的并行效果,能显著缩短时间消耗。

异步带来的好处是,提升CPU利用率(主线程的),并发IO,使得压榨更多底层服务的资源。

回到顶部