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()),然后开始执行事件循环。各个阶段执行的任务如下:
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的常用的功能和配置。
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 listpm2真心很好很强大,可以在线热更新代码,更多的指令需要上官网看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