瞎扯淡 有了解 node.js 的不,答疑一下吧

feitian124 · 2012年03月04日 · 最后由 fsword 回复于 2012年03月05日 · 5021 次阅读

今天点开 ruby-china 上的那个 node.js 的外链,在那社区里面闲逛,发现 node.js 很火。 之前也零零星星的看过一些 node.js 的介绍,知道它是底层是 google v8 引擎的基于事件模型的服务器软件。但脑子有几个 why 一直挥之不去:

1.基于事件模型的理论并不新鲜,为什么没有在其他语言中实现。可能的原因是,其他语言都没有基于基于事件模型的概念或者习惯,而在浏览器里运行的 js 则处处都是事件,onclick,onmouseover 等等。

2.在不是基于事件的 http 请求中,客户端和服务器建立 tcp 连接(http 都是基于 tcp 吧),直到响应完毕,断掉 tcp 连接。而现在 node.js 中不收到请求后,通知客户端断掉 tcp 连接,并说我之后会把找到的东西发给你。问题来了:服务器端是怎么找到客户器端的呢?我们知道客户端去找服务器端是花了不少力气的,现 dns,再 ip;现在 tcp 断了,我不知道有什么机制 能让服务器找到客户端?难道 node.js 不是用在这样的场景么?

好吧,精力有限,还来不及去研究这个问题的答案。哪位同学了解的话,解答一下吧。纯属解惑。

1.python 和 ruby 都有事件驱动的相关库,node 不也是基于 c 的神马 libev 吗?这模型挺广泛的啊,大公司里的程序员搞这个的好像挺多的 2.连接保持着,不能断了,服务器处理完还走这个连接

@clc3123 说的没错,事件驱动这事已经不新鲜了,ruby 程序员可以找 EventMachine 这个库看看。

另外补充一下,处理后释放的是当前线程(所以可以单线程工作),但是 tcp 连接等资源还是继续保留的

http://ruby-china.org/topics/962 看了这个帖子也是对 node 的讨论,但没找到我想知道的东西。 @clc3123 那如果都维持连接,那我可以这样理解么: java 维护开 1000 个线程维护 1000 个连接事件,有 线程空间成本,阻塞成本 node 基于事件排序处理 1000 个连接,有 队列对象的空间成本, 排序成本

我咋觉得一样啊,换种理解,我 排在第 1000 位的那个事件,还不是被前面 999 个阻塞着嘛

@fsword @alvin2ye 谢谢指点,对它的基本原理,我能理解的。不能理解的是问题 2 中的寻址问题, 如果如你们所说 tcp 资源保留,疑问倒弱了很多。 看来同步模型的阻塞成本很高。

这是一种非阻塞的设计,大约意思是你的 request 过来了,我 hold 住你的连接,把你的连接放进我的一个连接 pool 中,并注册成为一个事件,然后不再搭理这个请求,此时你的请求没有占用我什么资源。当事件被触发的时候,我把你的 http 连接找出来,再 response。其中客户端在服务器没有相应并释放这个连接之前是一直处于 wait 状态的。所以不是 tcp 断掉了,这个请求在服务器处理完事件并回返之前一直都没有释放的。

@soloara 非常感谢,很详细的解答。我的疑问可以 close 了。

#4 楼 @feitian124 嗯,有意思的回答,不过响应 1000 个线程和维护 1000 个连接,服务器肯定觉得后者会更舒服的。

1000 个人来申请宽带,他们依次领完了申请表。有个官员就绕着圈专门检查这 1000 个人哪个已经填完申请了,1 号可能是最早进来的,但要是每次官员经过的时候 1 号都没做完,官员就检查下一个,如果下一个先做完了,官员就先让下一个进去办事。所以说 1 号甚至可能是最晚进去的,但他不会阻塞其他人。

@clc3123 #9 呵呵,谢谢你写了这么多。不过你这个官员在多线程的 java 模型里也存在吧?某个线程先做完,肯定也是先返回了呀。

#9 楼 @clc3123 你这个例子不好,我听过一个经典的例子,有人去图书馆借书,打电话去问图书馆有这本书没有。A 图书管理员说,你不要挂我去给你找。B 图书管理员说,我知道了待会找到了我打电话给你,然后 B 就大叫 C 帮我看看 XXX 这本书有没有。结果就是 A 图书管理员在找书的时候别人要查书结果占线,而 B 管理员在 C 累死累活的时候接下了几个单。@clc3123 写完发现你的例子也挺好的。

#6 楼 @soloara 解释地很不错,不过我也有些疑问?搭个车。

第一 1000 个 http 连接(或者说 n 个 tcp 连接)只对应一个服务器线程,是这样吗?

第二 每个 http 连接都会有一个事件,那事件数量和线程数量的关系是什么哪?我的猜测是,node.js 后台有 n 个线程用来处理 x 个事件,n 和 x 没有直接关系,事件数量增加,不会导致线程数量的增加。我的猜测对吗?

#12 楼 @ery 第一条,“只对应” 可以改为 “可以只对应”。第二条,你的 http 连接可以不产生任何事件。比如我们在做服务器推送的时候,很多 waiting 的连接不过是为了侦听服务器的信息。

#13 楼 @soloara 谢谢你的回答, 第一条 “可以只对应” 很严谨,我认同。 第二条 你说,“你的 http 连接可以不产生任何事件”,这个我明白, 但是,我的问题是,假如 1000 个 http 连接,每个连接都产生了一个事件, 那事件数量和线程数量的关系是什么哪?

#14 楼 @ery 这个问题得看你自己怎么做了,比如 eventmachine 也没有管我们怎么处理逻辑。当然在 eventmachine 里面我以前的写法是基于事件的方式。只有一个线程。

#15 楼 sorry 说错了是 node.js,困死了。。。

#14 楼 @ery 服务器的本质就是调用 cpu 根据状态机逻辑处理各种数据。

如果你有 1000 个任务,但都是要 cpu 做的,那么别搞花样,老老实实按顺序做是最快的方式,后面排队的任务也只好等着。

但是,如果这里面有任务被 hold 住了(比如读写 socket),那么这时 cpu 是空闲的,后面排队的任务处于有计算资源却不能使用的状况,这才是我们常说的 “阻塞”,这时候我们最好的选择是——保留当前任务的工作现场,然后让 CPU“跳过” 这个任务先做下一个。

然而,如何保留现场?具体做起来却不那么简单,这里有两个问题:1、如何处理多核/多 CPU 之间的共享;2、是否由 OS 负责

发现写起来有些收不住了,强行打住,有空补充

需要 登录 后方可回复, 如果你还没有账号请 注册新账号