Node.js® is a JavaScript runtime built on Chrome’s V8 JavaScript engine. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient.
Node 是单线程, Event IO 模型,但服务器是 32 核心的,怎么充分利用。
Q: 进程,线程和 CPU 内核的对应关系?
线程只是用于分配单个处理器处理时间的一种机制。但假如操作系统本身支持多个 CPU/内核
,那么每个线程都可以得到一个不同自己的 CPU/内核
,实现真正的 并行运算
。在这种情况下,多线程程序可以提高资源使用效率。
- 单进程,单线程
- 单进程,多线程
- 多进程,单线程
- 多进程,多线程
操作系统才会关心进程,CPU 是没有进程的概念的?
- 线程是进程的一部分
- CPU 调度的是线程
- 系统为进程分配资源,不对线程分配资源
线程是cpu调度的一个基本单位,一个cpu同时只能执行一个线程的任务,同样一个线程任务也只能在一个cpu上执行
- 进程(Processes)和线程(Threads)
- https://github.com/DoubleSpout/threadAndPackage/blob/master/chapter.7.thread_and_process.md
Q: Node 的单线程
Node 是单线程程序,它只有一个 event loop
,也只占用一个 CPU/内核
。现在大部分服务器都是多 CPU 或多核的,当 Node 程序的 event loop 被 CPU 密集型的任务占用,导致有其它任务被阻塞时,却还有 CPU/内核
处于闲置的状态,造成资源的浪费。
同时一旦这个进程崩掉,那么整个 web 服务就崩掉了。
单线程的好处:
- 安全: 避免多个线程同时操作
- 简单: 不用并发锁
- 性能: 避免了频繁的线程切换开销
Q: Event-driven
Q: Non-blocking I/O Model
如何做到异步/非阻塞 I/O
的呢?
其实 Node 在底层访问 I/O
还是多线程的,有兴趣的朋友可以翻看 Node 的 fs 模块的源码,里面会用到 libuv 来处理 I/O,所以在我们看来 Node 的代码就是非阻塞和异步形式的。
Q: Node 单线程和多核
如何更好的利用多个 CPU/内核
,答案就是启动多进程。有两种方案:
- Nginx
- Culster/Webworker
这两种方案其实都是如何做反向代理和负载均衡。只是分发的工作谁来做 Nginx 天生是做这件事的,非常适合,但成本会比较高,毕竟每次都要配置。
Culster 成本就低不少,通过 PM2,只要启动时加一个参数,就可以指定 worker 的数量。而且支持自动创建新的 worker。
Q: Cluster 是什么,如何做到的
Taobao 有一篇好文,《当我们谈论 cluster 时我们在谈论什么 上 下》,详细讲解了 cluster 的原理。
Q: CPU/内核 和 Node 进程最佳配置
一般来说,有多少内核就分配多少个 worker。
Q: Node 的多线程
I/O 的多线程就是通过 libuv 来实现的。
Q: Docker 怎么利用多核?
Docker 不关心这些,给 Container 分配多少,就用多少,和在 host 中跑没有区别。
Q: Node 的适用场景
其实主要是 EventIO 的适用场景,大量 IO,网络请求的操作。
特别适合 API。
Q: 注意事项
- 一定不要阻塞线程
- 把运算型的方法,通过空间换时间。
Node.js软肋之CPU密集型任务
http://www.infoq.com/cn/articles/nodejs-weakness-cpu-intensive-tasks
Node.js的线程和进程
https://github.com/DoubleSpout/threadAndPackage/blob/master/chapter.7.thread_and_process.md