在node.js中顺序流程驱动的模块应该如何优化?

2012-10-08 13:14:56 +08:00
 xiao00000000
正在做一个APP的服务器端,外围的组建都是事件驱动的,只有内核还是顺序流程驱动。在内核里,要在每一次外围请求后遍历所有连接上的session的状态并做出相应处理,比如更改状态,分发通知。这样在连接数或业务逻辑增加后,内核在每一个请求周期所消耗的时间也就不断增加。由于node.js单线程的运行机制,内核就会成为瓶颈。考虑过用Cluster做负载均衡,但是由于请求后的业务逻辑流程比较碎片化,不容易移植到Cluster。且请求比较密集,担心“Experimental”状态中的Cluster会不稳定。

个人感觉在这种情况下使用其他的开发工具,使用传统的线程由操作系统进行任务分派或者使用协程自行协调任务会比较好。不过在node.js下没有这方面的经验,不知道是否合适。

请教各位,有没有比较好的方法解决这个问题?
3514 次点击
所在节点    Node.js
18 条回复
phuslu
2012-10-08 13:27:12 +08:00
试下 async 或者 step
hewigovens
2012-10-08 13:31:59 +08:00
@phuslu 哇,你什么时候精通nodejs了
phuslu
2012-10-08 13:44:47 +08:00
@hewigovens 汗, 比你差远啦.
xiao00000000
2012-10-08 14:50:57 +08:00
@phuslu 我需要的不是control-flow类型的功能,而是不阻塞node.js的主线程,另起线程执行,完成后通知主线程的功能。
step的源码我看了一下,是使用“process.nextTick”进行的处理,这样依然会在每一次耗时的callback的时候阻塞消息。
Cluster是可以满足这个需求的,但是由于启动进程的开销、“Experimental”的状态、还有碎片化的业务逻辑没有选择这个功能。
reus
2012-10-08 15:43:28 +08:00
虽然不懂nodejs,不过感觉可以把处理请求和“更改状态,分发通知”这些工作分开。用个任务队列,处理请求时只向队列里加任务,具体的执行由另外的进程/程序完成,这样就算逻辑再复杂也不会阻塞住处理请求的线程了
xiao00000000
2012-10-08 17:20:12 +08:00
@reus node.js的Cluster模块就是实现这种功能的,不过没有采用的原因我上面也提到了。
reus
2012-10-08 17:49:29 +08:00
@xiao00000000 看了下cluster的文档(http://nodejs.org/api/cluster.html#cluster_cluster),它只是多开启了几个node进程,并不是将请求处理和后台处理分开吧
我说的是这类:https://github.com/LearnBoost/kue,在处理请求的时候只是jobs.create,然后另外跑一个程序执行jobs.progress。
也就是处理请求和”更改状态,分发通知“在不同的进程/程序执行,这样就不会互相阻塞了。cluster也还是在同一个进程处理的
xiao00000000
2012-10-08 18:03:50 +08:00
@reus 如果用Cluster来解决这个问题,那就是fork出多个node进程,由Master进程监听连接和请求分派,由多个Worker进程负责业务逻辑的负载均衡,然后当每次操作完成后通过message通知Master进程处理结果。这个应该和你说的是一样的。
phuslu
2012-10-08 18:04:19 +08:00
@reus 从回帖来看楼主所说的"内核"操作估计是由一系列的的 CPU 密集型操作组成的, 这种硬碰硬的操作, nodejs/gevent 本身基本没啥好办法. 楼主不要 process.nextTick(callback), 那么觉得 SetTimeout(callback, 1) 如何呢, 呵呵.

最后, 楼主需要的可能是 golang
reus
2012-10-08 18:27:16 +08:00
@xiao00000000 原来如此
xiao00000000
2012-10-08 22:25:33 +08:00
@phuslu 我觉得不能算是CPU密集型的操作,毕竟对每个session的操作并不是很费时,只是有可能会有大量的session需要遍历。
如果用coroutine的话,类似下面的代码:
for i in xrang(0, session_num):
process_session(i)
stackless.schedule()
xiao00000000
2012-10-08 22:28:03 +08:00
@phuslu 我觉得我需要的其实是erlang。。。
meteor
2012-10-22 10:44:14 +08:00
Node.js底层是V8,主线程一个就够了.
其他的交给Google的V8引擎.
除非你的被把多线程管理的比Google好,一般不建议去碰底层的东西.
JavaScript不是C/C++.
aa88kk
2012-10-22 11:03:18 +08:00
你说的这种应用类似聊天室, 这正是nodejs擅长的. 连接多少不重要, 反正延迟主要都是在io上, 可以先测试下实际的响应速度是否能达到要求. 业务逻辑慢的话,可以试试用c++写nodejs模块.
clowwindy
2012-10-22 11:52:35 +08:00
CPU 密集型任务可以放在另外的进程里,用 redis 做任务队列。
xiao00000000
2012-10-22 14:12:20 +08:00
@clowwindy 如果要另起进程的话,就考虑Cluster了。其实node-fibers已经在考虑之列了。
xiao00000000
2012-10-22 14:15:36 +08:00
@meteor 线程对于node.js确实不是好方案,所以我在考虑用coroutine处理。
xiao00000000
2012-10-22 14:16:53 +08:00
@aa88kk 如果可以的话,我还是尽量不去写native-code的模块

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/49452

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX