前言
想了想,nodejs也在我的脑海里出现了多年了,但是我一直没有勇气(耐心)去和她交往,总是三天两头地想学,结果一把亚索就让我快乐地把她放弃了。最近不知道为啥,刚工作一年,就开始对未来产生了恐惧,到底该怎么样?在当前的公司勉强混下去?心有不甘,总想证明下自己,也是不凡的。又看了一些公司的招聘信息,花里胡哨的要求,让我望而却步,搞得像我从来没学过前端一样😵。但nodejs始终还是一个硬性要求,搞定了她,什么webpack、脚手架,命令行工具那还不是手到擒来,而且她能做的绝不仅是这些,还有更多的技能等着我解锁。
所以,我打算从今天开始,立下flag,每天学习一部分,凭借自己的学习记忆,在此做总结,与大家分享,望大家监督!
nodejs
我们在学习一门语言(不管学啥)的时候,一定要搞清楚几个概念:
- what: 到底是什么?能做什么?
- why:为什么要学?有什么特点?
- how:怎么学?怎么用?
什么是Node
Node的作者一开始只是想开发一个简单的web服务器,但是最后Node成为了构建网络应用的基础框架,在它的基础上可以构建更多的东西,
如服务器、命令行工具、客户端等。Node已经成为一个强制不共享任何资源的
单线程、单进程系统,包含适宜网络的库,为构建大型分布式应用提供基础设施,可构建快速可伸缩的网络平台。
每一个Node进程都是构成这个网络应用的节点,所以取名Node。
V8的力量
由于V8引擎的强大性能,使得chrome浏览器在市场的位置一马当先,Javascript语言可以在浏览器中大放异彩,构建美丽的界面, 调用浏览器提供的API与用户进行各种交互,但始终还是没能走出浏览器。而Node改变了这个现状。
它把Javascript与V8引擎结合起来,与浏览器保持相同的执行机制和原理,使得Javascript可以随意访问本地文件、连接数据库、 搭建websocket服务器、与webWorker一样实现多进程。
Node的特点
相比较于虚头八脑的讲历史,这应该成为大家对Node的第一印象:
-
异步IO
这很好理解,在我们做某件事的时候,不需要一直等着,我们只需要给它一个开始的命令,然后去做其他事,等它完成了,自然会通知我们, 这样我们就可以并行地做多件事情。
-
事件驱动
这也没什么好讲的,一个任务的执行,可能成功,也可能会失败,那么简单来说它就有两种状态,状态更新的时候,也就会触发对应的事件, 我们只需要监听对应的事件,就可以达到我们想要的目的。
-
单线程
其实这算是Javascript的特点,与浏览器中一样,Javascript在执行过程中,不与其他线程共享任何状态,同时只能有一行js代码在执行, 这也就避免了很多复杂的同步问题,同时也避免了切换线程上下文的开销成本。
既然单线程这么多好处,那为什么不所有语言都设计成单线程呢?因为单线程的缺点也是很明显的:
- 无法利用多核CPU
- 一旦代码运行出错,整个应用程序都会崩溃,不够健壮
- 大量的计算长时间占用CPU,导致无法再进行异步IO
和在浏览器中,js代码运算量过大会导致UI渲染卡顿一样的,如果Nodejs长时间占用CPU,会导致无法继续调用异步IO,而且已经完成的任务的 回调函数也得不到及时响应。
为了避免这一问题,浏览器端的
web worker应运而生,他可以创建一个单独用来计算的线程,将计算后的结果通过消息传递给主线程, 不会阻塞主线程,但也无法访问主线程中的UI。一样的,Node为了解决单线程的超大计算压力,
child_process出现了,子进程可以帮助我们缓解主进程Master-worker的压力, 可以利用多核CPU,提高了健壮性。各个子进程同样以事件消息来与主进程通信。 -
跨平台
Node可以在多个操作系统中运行,这主要是得益于Node在架构层面的改动,主要是
libuv,后面我们会讲到。
Node的应用场景
我们直奔主题:
-
IO密集型:
Node面向网络,可以并行处理IO,更加有效地组织起更多的硬件资源,得益于其事件循环的处理能力,并非为每一个请求服务开启一个线程, 资源占用很小,效率很高。
-
CPU密集型:
单看执行效率,由于V8引擎的强大,Node计算能力并不弱,CPU密集型业务只要的问题是,由于Javascript单线程,超大计算量导致的长时间 占用CPU时间片,无法及时释放,使得后续IO的调用受到阻塞。
但是我们可以通过分发计算,使得运算能够及时释放,不影响后续IO的调用,这样既可以并行处理IO,不受到阻塞,还充分利用了多核CPU。
-
分布式应用:
较为经典的是阿里巴巴的分布式应用,分布式应用对平台的可伸缩性要求很高,在数据平台中,通常会在一个数据库集群中去查找自己想要的数据, 阿里巴巴开发了中间层应用,NodeFox、ITier,将数据库集群做了划分和映射,查询的时候,依旧是针对单张表进行SQL查询,中间件分解 查询SQL,
并行地去多台数据库查询数据并合并,这也是高效并行IO的例子。