一、node.js
1、nodejs中间件
1】洋葱模型
洋葱模型顾名思义,指的是方法的执行像洋葱一样,每一层有3个参数(request、response和next)作为回调函数,由第3个参数回调函数next来驱动,一层一层往里执行,直到中心点后,再一层一层往外出来。
2】中间件是从http请求发起到响应结束过程中的处理方法,通常需要对请求和响应进行处理,如记录日志、ip过滤、查询字符串、请求体解析、Cookie处理、权限验证、参数验证、异常处理等,因此一个基本的中间件的形式如下:
const middleware = (req, res, next) => {
// TODO
next()
}
***中间件的原理:
最关键的就是中间件里面的next(),next函数实际上就是将其返回值用Promise包裹住,使其在业务处理完成后,通过Promise的then回调来继续处理中间件逻辑。当然也可以用async和await实现, 写法会更优雅和简单。
3】常用的一些插件
body-parser:HTTP请求体解析的中间件,使用这个模块可以解析JSON、Raw、文本、URL-encoded格式的请求体。
moment mysql node-xlsx request socket.io xml2js
4】如何和MySQL进行通信?
使用mysql模块,配置好相应的ip账号密码数据库名
mysql池需要设置连接次数(connectionLimit)和连接超时时间(connectTimeout)
2、有没有涉及到Cluster?(单核变多核)
1)理论
1】nodejs是单进程单线程的,而cluster是一个nodejs内置的模块,用于nodejs多核处理,轻松构建一个用于负载均衡的集群。
2】master是总控节点,worker是运行节点。然后根据CPU的核数,启动worker。我本地是双核双通道的CPU,所以被检测为4核,启动了4个worker。
3】每个worker进程是master通过使用child_process.fork()函数,基于IPC(Inter-Process Communication,进程间通信),实现与master进程间通信。
当worker使用server.listen(…)函数时 ,将参数序列传递给master进程。如果master进程已经匹配workers,会将传递句柄给工人。如果master没有匹配好worker,那么会创建一个worker,再传递并句柄传递给worker。
2】实际应用
在实际应用中,更多会用到pm2,因为pm2就是对cluster的进一步封装。
把应用部署到服务器所有的CPU上:pm2 start app.js -i max
比如服务器的CPU有8个核,那以上的命令就起了8个node进程
child_process模块,来实现进程的复制
问题:
这些进程间如何通信?
通过child_process 的 spawn() 方法的 stdio 选项可以建立IPC机制(Inter-Process Communication)
on监听消息 send发送消息
3、请简述一下node的多进程架构
面对node单线程对多核CPU使用不足的情况,Node提供了child_process模块,来实现进程的复制,node的多进程架构是主从模式,如下所示:
4、创建子进程的方法大致有:
spawn():启动一个子进程来执行命令
exec(): 启动一个子进程来执行命令,与spawn()不同的是其接口不同,它有一个回调函数获知子进程的状况
execFlie(): 启动一个子进程来执行可执行文件
fork(): 与spawn()类似,不同电在于它创建Node子进程需要执行js文件
spawn()与exec()、execFile()不同的是,后两者创建时可以指定timeout属性设置超时时间,一旦创建的进程超过设定的时间就会被杀死
exec()与execFile()不同的是,exec()适合执行已有命令,execFile()适合执行文件。
5、请问实现一个node子进程被杀死,然后自动重启代码的思路(递归)
在创建子进程的时候就让子进程监听exit事件,如果被杀死就重新fork一下
在上面基础上,实现限量重启,比如最多让其在1分钟内重启5次,超过了就报警给运维
思路大概是在创建worker的时候,就判断创建的这个worker是否在1分钟内重启次数超过5次
所以每一次创建worker的时候都要记录这个worker 创建时间,放入一个数组队列里面,每次创建worker都去取队列里前5条记录
如果这5条记录的时间间隔小于1分钟,就说明到了报警的时候了
(或者直接用pm2,更省事~)
6、pm2怎么做进程管理,进程挂掉怎么处理
pm2 基于 cluster模块 进行了封装
1】pm2特点
支持进程行为配置(可以给进程起名);支持集群模式;支持热重启;支持日志管理
同时,pm2还有可视化的监控界面。
比起forever,pm2清晰地看见整个集群的模式、状态,CPU利用率甚至是内存大小。
2】pm2启动命令
pm2 start app.js --name xxx
3】进程挂掉怎么处理
若检测到node相关进程挂了,pm2会立即将其重启
使用fork()创建子进程,子进程用于执行具体功能,主进程只是用于监控子进程,当主进程检测到子进程挂掉后,可以实现立即重新启动子进程
4】不用pm2怎么做进程管理
a、使用forever模块
b、使用supervisor模块
c、./node app.js & 运行于后台,然后在服务器上面写个shell脚本,定时去监听这个进程是否存活,如果不存活,则发送邮件报警并将其重启
7、nodejs服务如何热重启?(fs.watch)
1】用pm2
pm2 start app.js --watch
上述命令可以检测文件的改变,然后重新启动NodeJs服务
2】原理
通过监视文件被改动的时候,将缓冲区中已加载的对应模块清除,此时缓冲区中就不保留有该文件模块的代码,直至下一个请求该文件模块到来时,才会去重新加载一遍对应的模块,而正是改动之后的文件模块
Module._load = function(request, parent, isMain) {
var filename = Module._resolveFilename(request, parent);
var cachedModule = Module._cache[filename];
if (cachedModule) {
return cachedModule.exports;
}
var module = new Module(filename, parent);
Module._cache[filename] = module;
module.load(filename);
return module.exports;
};
require.cache = M