node是基于V8引擎之上的,它的模型跟浏览器类似:JavaScript运行在单个进程的单个线程上。
但是严格上,node并非真正的单线程架构。其自身还存在一定的I/O线程,由底层libuv处理,这部分线程对于js开发者是透明的,有在C++扩展开发是才会关注。
JavaScript代码永远运行在V8上, 是单线程的。
如同浏览器一样,ajax等I/O操作也是由浏览器其他(网络)线程(或进程)来实现。
单线程
Node保持了JavaScript在浏览器中单线程的特点。
无需考虑多线程编程那样的状态同步问题,也无线程上下文交换所带来的性能上的开销。
但是也带来写弱点:
- 无发利用多核CPU
- 错误会引起整个应用的退出,健壮性不好
- 大量计算占用CPU导致无发继续调用异步I/O,如同浏览器端js长时间执行导致UI渲染被中断
在浏览器端,H5新增了web workers来创建工作线程来进行计算,解决js大计算解决阻塞UI的问题
在node端,新增child_process子进程来分担计算工作
异步
在用户体验层面
I/O 是昂贵的,分布式I/O 是更昂贵的。
如果使用同步,获取资源时长将是:M1+M2+M3+…
如果使用异步,获取资源时长则是:Max(M1,M2,M3,…)
在资源分配层面
计算机资源中,通常I/O与cpu就算之间是可以并行进行的。
但是同步编程模型,I/O进行,会让后续任务等待,无发充分利用CPU资源。
实际多核计算机中,往往起多个工作进程来提升响应用户的请求。但是对于单个用户请求而言,无发分发到多个进程上,还是无发有效提高利用率。这种方式相当于加服务器。
单线程同步编程模型会因阻塞I/O导致硬件资源得不到更优的使用
多线程编程模型也因为编程中的死锁、状态同步等问题让开发人员头疼
Node则利用单线程,远离多线程死锁、状态同步等问题;利用异步I/O,让单线程远离阻塞,以更好的利用cpu