Node.js
是从纯前端走向更高阶层的前端,以及全栈工程师的惟一快速途径Node.js
就是运行在服务端的 JavaScript
Node.js
是一个基于Chrome JavaScript
运行时创建的一个平台Node.js
是一个事件驱动I/O
服务端JavaScript
环境,基于Google
的V8
引擎,V8
引擎执行Javascript
的速度很是快,性能很是好PHP
、Python
或Ruby
等动态编程语言,而后你想建立本身的服务,那么Node.js
是一个很是好的选择Node.js
是运行在服务端的 JavaScript
,若是你熟悉Javascript
,那么你将会很容易的学会Node.js
Node.js
也是一个很是好的选择Node.JS
适合运用在高并发、I/O
密集、少许业务逻辑的场景Node.js
的模块组成以下:Node.js
的运行机制JavaScript
脚本Node API
libuv
库负责Node API
的执行。它将不一样的任务分配给不一样的线程,造成一个EventLoop
(事件循环),以异步的方式将任务的执行结果返回给V8引擎。V8
引擎再将结果返回给用户。(Event Loop)
Nodejs
执行以后会初始化一个事件循环,执行代码程序(这些程序可能会形成异步调用、定时器或者process.nextTick()
),而后开始执行事件循环。各个阶段执行的任务以下:php
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
中的事件循环机制不会掉头,只会由上往下,循环执行。
在Node.js
中,绝大部分API
都是异步的,有一个很形象的故事描述了JAVA和Node.js
的区别,JAVA
是一个餐厅100
个服务员对应100
客户,Node.js
是一个服务员玩命干,也对应100
个客户,上菜的速度很大一部分取决于厨师的作菜速度
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
声称它不容许使用锁,它不会直接阻塞 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的经常使用的功能和配置。node
fork
模式,单实例多进程,经常使用于多语言混编,好比php、python
等,不支持端口复用,须要本身作应用的端口分配和负载均衡的子进程业务代码。缺点就是单服务器实例容易因为异常会致使服务器实例崩溃。python
cluster
模式,多实例多进程,可是只支持node
,端口能够复用,不须要额外的端口配置,0代码实现负载均衡。优势就是因为多实例机制,能够保证服务器的容错性,就算出现异常也不会使多个服务器实例同时崩溃。webpack
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
开启多线程,负载均衡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
之争高并发下的性能测试对比:
Apache、Nginx 与 Node.js
之争 i7-2600k
,四核八线程的机器Gentoo Linux
是用于测试的操做系统ApacheBench,2.3 <$Revision: 1748469 $>
咱们能够从结果中获得什么?
全面考虑
PHP 与 Node.js 的对决
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