Nodejs基础知识整理

                                                                     NodeJS基础知识html

 关于Node的火热程度和简介想必也不用多说,这里就简单的描述一下,Nodejs做者Ryan Dahl,初衷是单纯的开发一个Web服务器,可是项目的发展超出了他的预期值。为何Node要选择JavaScript做为实现的语言,这得益于Chrome的V8引擎的出色性能,CommonJS标准的制定,符合事件驱动,还有一点JavaScript的群众基础大同时门槛相比于C/C++较低,同时尽管服务端JavaScript以前已经存在,可是没有市场,因此没有市场包袱,固然也离不开生态社区中诸多开发者无私的贡献,以上种种造就了Nodejs的火爆。html5

1. 为何说Node吞吐量大?node

    Node的机制,保留了JavaScript在浏览器中单线程的特色,对于进来的请求不是在后台启动一个线程来单独跟踪 ,而是利用事件轮询机制处理,单独开启一个线程是须要消耗CPU内存的,好比你CPU不行,进来1000个请求,你的CPU就蹦了,因此传统的解决方案就是添加NLB负载均衡来缓解CPU的的压力。可是对于Node来讲则会大大改善这一问题,由于它采用的是事件轮询回掉的机制,采用异步I/O 编程,利用单线程,原理多线程死锁,状态同步等问题,同时远离阻塞,更好的利用CPU,这也是Node吞吐量大的缘由。web

2. 为何说Node速度快?express

    先说一下Node到底有多快,相比于静态语言C和C++仍是比不过的,不过也能够说是仅次于那些静态语言。为何这样说,以前已经简单的说了它的机制是事件轮询和链式回掉,这也是区别于传统的方式,规避掉了多线程并行的方式,减小CPU的消耗,避免了了一些数据共享与死锁的问题,其次,Node的内建模块是有C/C++编写(以下图),说明了Node模块底层的处理速度。再者是Node的缓存机制,对于内建模块再被调用时是直接转化为二进制缓存到本地。npm

    

3. 什么是异步I/O?编程

    在说异步I/O以前先来明确几个概念,同步/异步, 阻塞/非阻塞,首先同步异步与阻塞非阻塞不是一回事儿,同步/异步没错就是你想的那样,而阻塞和非阻塞是在面向系统内核来讲分为阻塞IO/非阻塞IO,区别在因而否会当即返回结果,阻塞的是等完整的IO完成以后返回完整IO,而非阻塞是当即返回IO的状态,而后经过屡次重复判断来确认是否完成完整IO,这个重复判断的操做叫作轮询。其实不管阻塞和非阻塞,都有本身的缺点,期待的完美的异步IO示意图应该以下,不浪费任何CPU资源同时完成完整IO的时还能及时返回。json

    其实也就是Windows下IOCP异步I/O模型,Linux下是另外一种类似的模型暂不去探讨,在IOCP之上,Node提供了Libuv做为抽象封装层,同时兼容多平台。windows

4. 什么是Node的事件轮询(Event Loop)?数组

    在说Node事件轮询以前,我们先了解一下JavaScript的事件轮询(在浏览器中的行为)。在JavaScript中的事件轮询说白了就是方法以参数的形式被传递,而后以同步的方式执行方法,也就是常说的callback,执行在单线程上。

    还要补充先说明一下Node的单线程实际上是在执行JavaScript的时候是单线程,Node自身时候有线程池的概念的,相似有web worker的子线程。Node的事件轮询是在进程启动时,Node便会建立一个相似与While(true)的循环,每执行一次循环成为一个次Tick,在Tick的过程当中查看是否有事件须要被处理,若是有就取出事件和相关的callback,而后执行,再以后下一次循环重复相同动做。不过这里的事件由来是很复杂的过程,首先从咱们调用开始到系统内核会一个叫作请求对象的概念,也就是libuv封装层根据具体平台建立一个适合与具体平台应用的一个对象例如windows的FSReqWrap请求对象,而后会把咱们调用的方法的参数和callback函数添加到这个生成的对象的属性上,而后调用相应的底层函数,当前I/O操做也就再线程池中等待执行了,咱们调用的JavaScript被函数被当即返回,不会阻塞后续的JavaScript操做,至此我们这个调用完成了第一部分。而咱们最关心的是刚才被添加到底层对象属性上的callback函数,callback函数会在何时执行那?实际上是这样的,刚才咱们的I/O操做已是在线程池中处于被等待执行的状态,若是如今有空闲的线程就会执行咱们的操做,咱们的操做结果会被存在FSReqWrap的result属性上,而后调用PostQueuedCompletetionStatus()同时给IOCP,而后每次Tick的时候调用GetQueuedCompletionStatus()方法来检查县城时候是否有执行完成的请求,若是存在会将请求对象做为事件处理,这也就是上面说的事件的由来。通读以后是否是有种豁然开朗的感受。还有若是一点callback函数的trigger是在I/O观察者的回掉方法中执行(每一个事件循环都会有至少一个的观察者),取出以前我们添加到请求对象属性上的方法进行调用。

5. Node构建Web服务器的执行流程是什么样的?

    其实若是你对上面都已经理解基本上也就知道了大概的执行流程,下面的图给出一个参考。

6. NPM与包。

    包和NPM是将模块之间联系起来的一种机制。以下图。CommonJS包规范定义中包含两点包结构和包描述文件。

    

      · 包结构

package.json 包描述文件
bin 用于存放可执行二进制文件的目录
lib 用于存放JavaScript代码的目录
doc 用于存放文档的目录
test 用于存放单元测试用例的代码

    · 包描述文件与NPM

              建立一个packgage.json文件能够手动建立与根目录下,或者用npm init命令,根据提示填写。

name 包名
description 包简介
version 版本号
keywords 关键词数组
maintainers 包维护者 example=> “maintainers”: [{"name": "Jackson Tian", "email": "shyvo1987@gmail.com", "web": "http://html5ify.com"}]
contributors 贡献者列表
bugs 一个能够反馈bug的网页地址或者邮箱地址
licenses 当前包所使用的许可证列表 example=> "licenses": [{"type": "GPLv2", "url": "http://www.example/licenses/gpl.html"}]
repositories 托管源代码的位置列表
dependencies 当前包所须要的依赖包列表
homepage 当前包的网站地址
os 操做系统
cpu CPU架构的支持列表
engine 支持的JavaScript引擎列表
builtin 标志当前包是不是内建在底层系统的标准组建
directories 包目录说明
scripts 脚本说明对象
author 包做者
bin 一些包做者但愿包能够做为命令行工具使用
main 模块引入方法require()在引入包时会优先检查这个字段,并将其做为包中其他模块的入口,若是不存在这个字段,require()方法会自动查找包目录下的index.js,index.node,index.json文件做为默认入口

                                   对于Node而言NPM基于以上规范解决依赖包的安装问题,同时帮助完成了第三方模块的发布,安装和依                              赖等。借助NPM,Node与第三方模块之间造成了很好的生态系统。

               · NPM经常使用命令

                          npm -v  查看版本号

                         npm install express  NPM会在当前目录下建立node_modules目录,而后在node_modules目录下建立express目录,而后把包解压到这个目录下。

                         npm install express -g  进行全局安装,并非从任何地方均可以经过require()引用到它,而是须要经过软链接的方式连接到Node的可执行目录下。也就是须要在package.json的bin字段下进行配置。

                         npm install <tarball file/ tarball url/ folder> 当网络很差的时候能够把包download到本地,而后从本地进行安装。

                         npm install --registry=http://registry.url 使用镜像进行安装,如淘宝镜像须要把镜像地址替换成淘宝镜像。

                         npm config set registry http://registry.url 设置淘宝镜像。

                         npm uninstall <package> 包卸载

                         npm test 运行测试用例,一个优秀的包中应该包含测试用例,以便检查包是否稳定可靠。

                         npm adduser 发布包时的前提,你得注册了仓库管理帐号。若是你尚未仓库帐号就去仓库传送门吧。

                         npm publish 开发发布。

                         npm owner ls <package> 查看包拥有者

                         npm owner add <user> <package> 添加拥有者

                         npm owner rm <user> <package> 删除一个拥有者

                         npm ls 分析包,列出能够经过require()引入的全部包,并生成依赖树。

 

至此,Node比较基础的概念和原理就先介绍到这,以上为我的理解,不到之处望海涵与指正。