Node.js
是从纯前端走向更高阶层的前端,以及全栈工程师的惟一快速途径简单的说Node.js
就是运行在服务端的 JavaScript
php
Node.js
是一个基于Chrome JavaScript
运行时创建的一个平台前端
Node.js
是一个事件驱动I/O
服务端JavaScript
环境,基于Google
的V8
引擎,V8
引擎执行Javascript
的速度很是快,性能很是好node
PHP
、Python
或Ruby
等动态编程语言,而后你想建立本身的服务,那么Node.js
是一个很是好的选择Node.js
是运行在服务端的 JavaScript
,若是你熟悉Javascript
,那么你将会很容易的学会Node.js
python
固然,若是你是后端程序员,想部署一些高性能的服务,那么学习Node.js
也是一个很是好的选择webpack
Node.JS
适合运用在高并发、I/O
密集、少许业务逻辑的场景Node.js
的模块组成以下:Node.js
的运行机制JavaScript
脚本Node API
libuv
库负责Node API
的执行。它将不一样的任务分配给不一样的线程,造成一个EventLoop
(事件循环),以异步的方式将任务的执行结果返回给V8引擎。V8
引擎再将结果返回给用户。(Event Loop)
Nodejs
执行以后会初始化一个事件循环,执行代码程序(这些程序可能会形成异步调用、定时器或者process.nextTick()
),而后开始执行事件循环。nginx
事件循环的执行循序:程序员
各个阶段执行的任务以下:web
timers 阶段
: 这个阶段执行setTimeout
和setInterval
预约的callback
;I/O callbacks
阶段: 执行除了close
事件的callbacks
、被timers
设定的callbacks
、setImmediate()
设定的callbacks
这些以外的callbacks
;idle, prepare
阶段: 仅node内部使用;poll
阶段: 获取新的I/O事件, 适当的条件下node
将阻塞在这里;check
阶段: 执行setImmediate()
设定的callbacks
;close callbacks
阶段: 执行socket.on('close', ...)
这些 callback
process.nextTick()
不属于上面的任何一个phase
,它在每一个phase
结束的时候都会运行。也能够认为,nextTick
在下一个异步方法的事件回调函数调用前执行。
TIPS:
Node.js
中的事件循环机制不会掉头,只会由上往下,循环执行。ajax
在
Node.js
中,绝大部分API
都是异步的,有一个很形象的故事描述了JAVA和Node.js
的区别,JAVA
是一个餐厅100
个服务员对应100
客户,Node.js
是一个服务员玩命干,也对应100
个客户,上菜的速度很大一部分取决于厨师的作菜速度redis
I/O
操做完以后呢?Node.js
的I/O
处理完以后会有一个回调事件,这个事件会放在一个事件处理队列里头,在进程启动时node会建立一个相似于While(true)
的循环,它的每一次轮询都会去查看是否有事件须要处理,是否有事件关联的回调函数须要处理,若是有就处理,而后加入下一个轮询,若是没有就退出进程,这就是所谓的“事件驱动”。这也从Node
的角度解释了什么是”事件驱动”。
在node.js
中,事件主要来源于网络请求,文件I/O
等,根据事件的不一样对观察者进行了分类,有文件I/O观察者,网络I/O观察者。事件驱动是一个典型的生产者/消费者模型,请求到达观察者那里,事件循环从观察者进行消费,主线程就能够快马加鞭的只关注业务不用再去进行I/O
等待。
优势: Node
公开宣称的目标是 “旨在提供一种简单的构建可伸缩网络程序的方法”。咱们来看一个简单的例子,在 Java和 PHP 这类语言中,每一个链接都会生成一个新线程,每一个新线程可能须要2MB的配套内存。在一个拥有8GBRAM的系统上,理论上最大的并发链接数量是4,000
个用户。随着您的客户群的增加,若是但愿您的Web应用程序支持更多用户,那么,您必须添加更多服务器。因此在传统的后台开发中,整个Web应用程序架构(包括流量、处理器速度和内存速度)中的瓶颈是:服务器可以处理的并发链接的最大数量。这个不一样的架构承载的并发数量是不一致的。
而Node的出现就是为了解决这个问题:更改链接到服务器的方式。在Node
声称它不容许使用锁,它不会直接阻塞 I/O
调用。Node
在每一个链接发射一个在 Node 引擎的进程中运行的事件,而不是为每一个链接生成一个新的 OS 线程(并为其分配一些配套内存)。
缺点:如上所述,nodejs
的机制是单线程,这个线程里面,有一个事件循环机制,处理全部的请求。在事件处理过程当中,它会智能地将一些涉及到IO、网络通讯等耗时比较长的操做,交由worker-threads
去执行,执行完了再回调,这就是所谓的异步IO非阻塞吧。可是,那些非IO操做,只用CPU计算的操做,它就本身扛了,好比算什么斐波那契数列之类。它是单线程,这些本身扛的任务要一个接着一个地完成,前面那个没完成,后面的只能干等。所以,对CPU要求比较高的CPU密集型任务多的话,就有可能会形成号称高性能,适合高并发的node.js服务器反应缓慢。
Node.js
高并发使用Nginx+pm2
,pm2
中能够开启多线程负载均衡,模式分两种:
pm2
简介:PM2
是node
进程管理工具,能够利用它来简化不少node
应用管理的繁琐任务,如性能监控、自动重启、负载均衡等,并且使用很是简单。
下面就对PM2进行入门性的介绍,基本涵盖了PM2的经常使用的功能和配置。
fork
模式,单实例多进程,经常使用于多语言混编,好比php、python
等,不支持端口复用,须要本身作应用的端口分配和负载均衡的子进程业务代码。 缺点就是单服务器实例容易因为异常会致使服务器实例崩溃。
cluster
模式,多实例多进程,可是只支持node
,端口能够复用,不须要额外的端口配置,0代码实现负载均衡。 优势就是因为多实例机制,能够保证服务器的容错性,就算出现异常也不会使多个服务器实例同时崩溃。
共同点,因为都是多进程,都须要消息机制或数据持久化来实现数据共享。
pm2
部署,默认开启负载均衡:npm i pm2 -g
$ pm2 start app.js # 启动app.js应用程序
$ pm2 start app.js -i 4 # cluster mode 模式启动4个app.js的应用实例 # 4个应用程序会自动进行负载均衡
pm2 start app.js -i max 根据你的cpu数量最大化启动多线程进行负载均衡
若是要中止全部应用,能够pm2 stop all
查看进程状态 pm2 list
pm2真心很好很强大,能够在线热更新代码,更多的指令须要上官网看
pm2
和Nginx
配合upstream my_nodejs_upstream {
server 127.0.0.1:3001;
}
server {
listen 80;
server_name my_nodejs_server;
root /home/www/project_root; location / { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_max_temp_file_size 0; proxy_pass http://my_nodejs_upstream/;
proxy_redirect off; proxy_read_timeout 240s;
}
复制代码
特别说明,咱们不建议使用
Node.js
做为底层服务器,更多时候做为中间件和接入层使用,例如Electron
开发跨平台应用
Nginx
开启多线程,负载均衡源地址哈希法:根据获取客户端的IP地址,经过哈希函数计算获得一个数值,用该数值对服务器列表的大小进行取模运算,获得的结果即是客服端要访问服务器的序号。采用源地址哈希法进行负载均衡,同一IP地址的客户端,当后端服务器列表不变时,它每次都会映射到同一台后端服务器进行访问。
轮询法:将请求按顺序轮流地分配到后端服务器上,它均衡地对待后端的每一台服务器,而不关心服务器实际的链接数和当前的系统负载。
随机法:经过系统的随机算法,根据后端服务器的列表大小值来随机选取其中的一台服务器进行访问。
加权轮询法:不一样的后端服务器可能机器的配置和当前系统的负载并不相同,所以它们的抗压能力也不相同。给配置高、负载低的机器配置更高的权重,让其处理更多的请;而配置低、负载高的机器,给其分配较低的权重,下降其系统负载,加权轮询能很好地处理这一问题,并将请求顺序且按照权重分配到后端。
加权随机法:与加权轮询法同样,加权随机法也根据后端机器的配置,系统的负载分配不一样的权重。不一样的是,它是按照权重随机请求后端服务器,而非顺序。
最小链接数法:因为后端服务器的配置不尽相同,对于请求的处理有快有慢,最小链接数法根据后端服务器当前的链接状况,动态地选取其中当前积压链接数最少的一台服务器来处理当前的请求,尽量地提升后端服务的利用效率,将负责合理地分流到每一台服务器。
下载Nginx
,找到config
文件夹下面的nginx.conf
,修改下面配置文件
每一个
upstream test{
server 11.22.333.11:6666 weight=1;
server 11.22.333.22:8888 down;
server 11.22.333.33:8888 backup;
server 11.22.333.44:5555 weight=2;
}
//down 表示单前的server临时不參与负载.
//weight 默以为1.weight越大,负载的权重就越大
//backup: 其余所有的非backup机器down或者忙的时候,请求backup机器。因此这台机器压力会最轻
复制代码
nginx
命令汇总 :nginx 服务器重启命令,关闭
nginx -s reload :修改配置后从新加载生效
nginx -s reopen :从新打开日志文件
nginx -t -c /path/to/nginx.conf 测试nginx配置文件是否正确
关闭nginx:
nginx -s stop :快速中止nginx
quit :完整有序的中止nginx
其余的中止nginx 方式:
ps -ef | grep nginx
kill -QUIT 主进程号 :从容中止Nginx
kill -TERM 主进程号 :快速中止Nginx
pkill -9 nginx :强制中止Nginx
启动nginx:
nginx -c /path/to/nginx.conf
平滑重启nginx:
kill -HUP 主进程号
复制代码
Nginx
多线程负载均衡和部署pm2
负载均衡后的架构图:Node.js
做为底层服务器,直接操做数据库的方式:Node.js
做为中间件,访问底层服务器的方式:Apache、Nginx 与 Node.js
之争高并发下的性能测试对比:
全部的测试都在本地运行:
英特尔酷睿 i7-2600k
,四核八线程的机器
Gentoo Linux
是用于测试的操做系统
用于基准测试的工具:ApacheBench,2.3 <$Revision: 1748469 $>
测试包括一系列基准,从 1000 到 10000 个请求以及从 100 到 1000 个的并发请求——结果至关使人惊讶。
咱们能够从结果中获得什么?
从以上结果判断,彷佛 Nginx 能够在最少的时间内完成最多请求,换句话来讲,Nginx 是最快的 HTTP 服务器。
还有一个至关惊人的事实是,在特定的用户并发数和请求数下,Node.js 能够比 Nginx 和 Apache 更快。
但当请求的数量在并发测试中增长的时候,Nginx 将重回领先的位置,这个结果可让那些陷入 Node.js 的遐想的人清醒一下。
和 Apache、Nginx 不一样的是,Node.js 彷佛对用户的并发数不太敏感,尤为是在集群节点。如图所示,集群节点在 0.1 秒左右保持一条直线,而 Apache 和 Nginx 都有大约 0.2 秒的波动。
基于上述统计能够得出的结论是:网站比较小,其使用的服务器就无所谓。然而,随着网站的受众愈来愈多,HTTP 服务器的影响变得越发明显。
当涉及到每台服务器的原始速度的底线的时候,正如压力测试所描述的,个人感受是,性能背后最关键的因素不是一些特定的算法,而其实是运行的每台服务器所用的编程语言。
因为 Apache 和 Nginx 都使用了 C 语言—— AOT 语言(编译型语言),而 Node.js 使用了 JavaScript ——这是一种 JIT 语言(解释型语言)。这意味着 Node.js 在执行程序的过程当中还有额外的工做负担。
这意味着我不能仅仅基于上面的结果来下结论,而要作进一步校验,正如你下面看到的结果,当我使用一台通过优化的 Node.js 服务器与流行的 Express 框架时,我获得几乎相同的性能结论。
全面考虑
逝者如斯夫,若是没有服务的内容,HTTP 服务器是没什么用的。所以,在比较 we服务器的时候,咱们必须考虑的一个重要的部分就是咱们但愿在上面运行的内容。
虽然也有其它的功能,可是 HTTP 服务器最普遍的使用就是运行网站。所以,为了看到每台服务器的性能的实际效果,我决定比较一下世界上使用最普遍的 CMS(内容管理系统)WordPress 和 Ghost —— 内核使用了 JavaScript 的一颗冉冉升起的明星。
基于 JavaScript 的 Ghost 网页可否赛过运行在 PHP 和 Apache / Nginx 上面的 WordPress 页面?
这是一个有趣的问题,由于 Ghost 具备操做工具单一且一致的优势——无需额外的封装,而 WordPress 须要依赖 Apache / Nginx 和 PHP 之间的集成,这可能会致使显著的性能缺陷。
除此以外,PHP 距 Node.js 之间还有一个显著的性能落差,后者更佳,我将在下面简要介绍一下,可能会出现一些与初衷截然不同的结果。
PHP 与 Node.js 的对决
为了比较 WordPress 和 Ghost,咱们必须首先考虑一个影响到二者的基本组件。
基本上,WordPress 是一个基于 PHP 的 CMS,而 Ghost 是基于 Node.js(JavaScript)的。与 PHP 不一样,Node.js 有如下优势:
非阻塞的 I/O
事件驱动
更新颖、更少的残旧代码
因为有大量的测评文章解释和演示了 Node.js 的原始速度超过 PHP(包括 PHP 7),我不会再进一步阐述这个主题,请你自行用谷歌搜索相关内容。
所以,考虑到 Node.js 的性能优于 PHP,一个 Node.js 的网站的速度要比 Apache / Nginx 和 PHP 的网站快吗?
WordPress 和 Ghost 对决
当比较 WordPress 和 Ghost 时,有些人会说这就像比较苹果和橘子,大多数状况下我赞成这个观点,由于 WordPress 是一个彻底成熟的 CMS,而 Ghost 基本上只是一个博客平台。
然而,二者仍然有共同竞争的市场,这二者均可以用于向世界发布你的我的文章。
制定一个前提,咱们怎么比较两个彻底基于不一样的代码来运行的平台,包括风格主题和核心功能。
事实上,一个科学的实验测试条件是很难设计的。然而,在这个测试中我对更接近生活的情景更感兴趣,因此 WordPress 和 Ghost 都将保留其主题。所以,这里的目标是使两个平台的网页大小尽量类似,让 PHP 和 Node.js 在幕后斗智斗勇。
因为结果是根据不一样的标准进行测量的,最重要的是尺度不同,所以在图表中并排显示它们是不公平的。所以,我改成使用表:
Node、Nginx、Apache 以及运行 WordPress 和 Ghost 的比较。前两行是 WordPress,底部的两行是 Ghost
Node、Nginx、Apache 以及运行 WordPress 和 Ghost 的比较。前两行是 WordPress,底部的两行是 Ghost
正如你所见,尽管事实上 Ghost(Node.js)正在加载一个更小的页面(你可能会惊讶 1kb 能够产生这么大的差别),它仍然比同时使用 Nginx 和 Apache 的 WordPress 要慢。
此外,使用 Nginx 代理做为负载均衡器来接管每一个 Node 服务器的请求实际上会提高仍是下降性能?
那么,根据上面的表格,若是说它产生什么效果的话,它形成了更慢的效果——这是一个合理的结果,由于额外封装一层理所固然会使其变得更慢。固然,上面的数字也代表这点差别能够忽略不计。
可是上表中最重要的一点是,即便 Node.js 比 PHP 快,HTTP 服务器的做用也可能超过某个 web 平台使用的编程语言的重要性。
固然,另外一方面,若是加载的页面更多地依赖于服务器端的脚本处理,那么我怀疑结果可能会有点不一样。
最后,若是一个 web 平台真的想在这场竞赛里击败 WordPress,从这个比较中得出的结论就是,要想性能占优,必需要定制一些像 PHP-FPM 的工具,它将直接与 JavaScript 通讯(而不是做为服务器来运行),所以它能够彻底发挥 JavaScript 的力量来达到更好的性能。
Node.js
的生态圈汇总:Node.js
遵循commonJS
规范,要说它的生态圈,第一个确定是webpack
,用很差Node.js
的人确定用很差webpack
,因此说Node.js
的一个突破初级前端工程师的好学习方向express koa koa2 egg
一系列的Node.js
框架,在Restful
架构下使用,完成常规的一些http,ajax
请求响应GraphQL
,GraphQL
是一种 API 所使用的查询语言,不止Node.js
有,其余语言也有,不止能够查询,还能够多数据库CRUD
操做,解决了一部分RestFul
架构带来的问题mongodb
,非关系型数据库,轻量级别数据库,目前Node.js
配合使用的比较多的数据库,在Node.js
中咱们通常使用 mongoose
这个库来配合使用sqlite
,SQLite是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。它是一个零配置的数据库,这意味着与其余数据库同样,您不须要在系统中配置。就像其余数据库,SQLite 引擎不是一个独立的进程,能够按应用程序需求进行静态或动态链接。SQLite 直接访问其存储文件。Electron
,跨平台桌面开发,可使用Node.js
的API,V8的环境也被打包在内。C++
插件,Node.js
的V8环境就是C++写的,天然也是可使用C++插件Redis
,数据缓存层,Redis支持主从同步。数据能够从主服务器向任意数量的从服务器上同步,从服务器能够是关联其余从服务器的主服务器。这使得Redis可执行单层树复制。存盘能够有意无心的对数据进行写操做。因为彻底实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操做的可扩展性和数据冗余颇有帮助。SSR
, 以React
为例,在中间层对代码进行注水,在客户端对代码脱水,实现部分首屏SSR
,优化首屏渲染时间。websocket
通信等puppeteer
爬虫Node.js
在目前前端的开发中,是一项不可或缺的技能,它也是让咱们走向真正全栈工程师的路不那么陡峭Node.js
适用场景,非密集型计算型Node.js
最核心的部分不止是RestFul
架构的那一套接受请求,返回数据。还有文件IO
,流,Buffer
,redis层
这一类的操做Node.js
配合Nginx
进行负载均衡,不只能提高性能,更能替后端真正减轻不少负担,完成许多特定的需求。Node.js
在作接入层,好比Electron
中,能够调用不少Node API
,完成渲染进程不能作的事情,例如文件io
,buffer
操做等今天因为时间有限,不少东西都没有细化下去写,可能仍是有很多漏掉的,之后都会慢慢补上,走过路过,点点赞,我们永远都是A