node.js从诞生之初就是充分考虑了在实时响应、超大规模数据要求下的可扩展性。这使得他摈弃了传统平台依靠多线程来实现高并发的设计思路,而是采用了单线程、异步式I/O,事件驱动的程序设计模式。这些特性不仅带来了巨大的性能提升,还减少了多线程程序设计的复杂性,进而提高了开发效率。
Q1:单线程怎么可能榨干多核系统性能?
node.js最大的特点就是采用异步I/O与事件驱动的架构设计。对于高并发方案,传统的架构是多线程模型,也就是为每个业务逻辑提供一个系统线程,通过系统线程切换来弥补同步式I/O调度的时间开销。node.js是单线程模型,对于所有的I/O操作都采用异步请求方式,避免了频繁的上下文切换。node.js在支持的过程中会维护一个时间队列,程序在执行时进入时间循环等待下一个事件到来,每个异步I/O请求完成之后会被推送到事件队列,等待程序进行处理。
C1:每业务逻辑每线程应该是上个世纪的方案了。本世纪至少有任务池和线程池方案,牛逼的还有根据系统个逻辑任务的负载情况动态调度。
想起来网狐的AttempterEnging已经有这个味道了,只是没有提升到理论高度。
node.js最大的特点就是异步I/O与事件紧密结合的编程模式。这种模式与传统的同步模式I/O线型编程的思路有很大不同,应为控制流很大程序上要靠事件和回调来组织,一个逻辑要拆分成若干个单元。
异步I/O扩展一下就是把能“并发的逻辑抽取出来,让有空余负载的‘cpu’去执行,原负载‘cpu’可以去执行其他需要实时响应的逻辑”
node.js核心模块
process: processs是一个全局变量,即global对象的属性。他用于描述node.js进程的状态,提供一个与操作系统的简单接口。
console: console用于提供控制台标准输出,用于向标准输出流或标准输入流输出字符
事件发射器:
events模块只提供一个对象:events.EventEmitter,他的核心就是时间发射与事件监听功能的封装。EventEmitter的每个事件由一个事件名和若干个时间参数组成,事件名是一个字符串,通常表达一定的语义。对于每个事件EventEmitter支持若干个事件监听器。当时间发射时,注册到这个事件的监听器被依次调用,事件参数作为回调函数参数传递。
EventEmitter.on(event, listener) 为指定事件注册一个监听器,接收一个字符串event和一个回调函数listener
EventEmitter.emic(event, args) 发射event事件,传递若干个可选参数到事件监听器参数列表
EventEmitter.once(event, listener) 为指定事件注册一个单次监听器,即触发一次后自动解除注册
EventEmitter.removeListener(event, listener) 解除注册
EventEmitter.removeAllListeners(event) 移出所有时间的所有监听器
error事件:EventEmitter定义了一个特殊的事件Error,他包含了错误的语义,在遇到异常的时候通常会发射error事件,当error被发射时,EventEmitter规定如果没有相应的监听器,node.js会把它当作一场,退出程序并打印调用栈。
大多数时候不会直接用EventEmitter而是在对象中继承他,只要是支持事件响应的核心模块都是EventEmitter的子类。