下栽地止:https://lexuecode.com/4435.html
Node.js应用开发介绍
Node.js 是一个开源与跨平台的 JavaScript 运行时环境在浏览器外运行 V8 JavaScript 引擎(Google Chrome 的内核),利用事件驱动、非阻塞和异步输入输出模型等技术提高性能
可以理解为 Node.js 就是一个服务器端的、非阻塞式I/O的、事件驱动的JavaScript运行环境
Node.js优缺点
优点:
处理高并发场景性能更佳
适合I/O密集型应用,值的是应用在运行极限时,CPU占用率仍然比较低,大部分时间是在做 I/O硬盘内存读写操作
因为Nodejs是单线程,带来的缺点有:
不适合CPU密集型应用
只支持单核CPU,不能充分利用CPU
可靠性低,一旦代码某个环节崩溃,整个系统都崩溃
构建千万级高可用企业级Node.js应用实战 - Node.js内存管理 Node.js内存管理
不同于PHP这样的平台,Node.js应用是一个一直运行的进程。虽然这种机制有很多的优点,例如在配置数据库连接信息时, 只需要建立一次连接,便可以让所有的请求进行复用该连接信息,但不幸的是,这种机制也存在缺陷。 但是,首先我们还是来了解一些Node.js基本知识。
V8的内存管理模式
一个运行的程序通常是通过在内存中分配一部分空间来表示的。这部分空间被称为驻留集(Resident Set)。 V8的内存管理模式有点类似于Java虚拟机(JVM),它会将内存进行分段:
代码 Code:实际被执行的代码
栈 Stack:包括所有的携带指针引用堆上对象的值类型(原始类型,例如整型和布尔),以及定义程序控制流的指针。
堆 Heap:用于保存引用类型(包括对象、字符串和闭包)的内存段
在Node.js中,当前的内存使用情况可以轻松的使用process.memoryUsage进行查询, 实例程序如下:
var util = require('util');
console.log(util.inspect(process.memoryUsage));
【构建千万级高可用企业级Node.js应用吾爱】这将会在控制台产生如下结果:
{
rss: 4935680,
heapTotal: 1826816,
heapUsed: 650472
}
正如我们所看到的,垃圾收集是个非常复杂的过程,并且即使代码没有问题也有可能会导致内存泄漏。 通过使用v8(和chrome开发者工具)提供的一些开箱即用的功能,能够帮助我们定位问题的源头, 如果你将这种机制构建到你的应用内,这将会非常有助于你发现和修复问题。
当然,如果你问我上面的代码如何修复,其实非常的简单,只要在函数的最后加上一行theThing = null; 即可。
构建千万级高可用企业级Node.js应用实战 - 日志管理 安装
log4js
模块
npm i log4js -S
log4js
官方简单示例
在 middleware/
目录下创建 mi-log/demo.js
,并贴入官方示例代码:var log4js = require('log4js');
var logger = log4js.getLogger();
logger.level = 'debug';
logger.debug("Some debug messages");
然后在
/middleware/mi-log/
目录下运行:cd ./middleware/mi-log/ && node demo.js
可以在终端看到如下输出:
[2017-10-24 15:45:30.770] [DEBUG] default - Some debug messages
一段带有日期、时间、日志级别和调用
debug
方法时传入的字符串的文本日志。实现了简单的终端日志输出。log4js
官方复杂示例
替换 mi-log/demo.js
中的代码为如下:const log4js = require('log4js');
log4js.configure({
appenders: { cheese: { type: 'file', filename: 'cheese.log' } },
categories: { default: { appenders: ['cheese'], level: 'error' } }
});
const logger = log4js.getLogger('cheese');
logger.trace('Entering cheese testing');
logger.debug('Got cheese.');
logger.info('Cheese is Gouda.');
logger.warn('Cheese is quite smelly.');
logger.error('Cheese is too ripe!');
logger.fatal('Cheese was breeding ground for listeria.');
再次在
/middleware/mi-log/
目录下运行:node demo.js
运行之后,在当前的目录下会生成一个日志文件
cheese.log
文件,文件中有两条日志并记录了 error
及以上级别的信息,也就是如下内容:[2017-10-24 15:51:30.770] [ERROR] cheese - Cheese is too ripe!
[2017-10-24 15:51:30.774] [FATAL] cheese - Cheese was breeding ground for listeria.
注意: 日志文件产生的位置就是当前启动环境的位置。
分析以上代码就会发现,
configure
函数配置了日志的基本信息{
/**
* 指定要记录的日志分类 cheese
* 展示方式为文件类型 file
* 日志输出的文件名 cheese.log
*/
appenders: { cheese: { type: 'file', filename: 'cheese.log' } },/**
* 指定日志的默认配置项
* 如果 log4js.getLogger 中没有指定,默认为 cheese 日志的配置项
* 指定 cheese 日志的记录内容为 error 及 error 以上级别的信息
*/
categories: { default: { appenders: ['cheese'], level: 'error' } }
}
改写为log中间件 创建
/mi-log/logger.js
文件,并增加如下代码:const log4js = require('log4js');
module.exports = ( options ) => {
return async (ctx, next) => {
const start = Date.now()
log4js.configure({
appenders: { cheese: { type: 'file', filename: 'cheese.log' } },
categories: { default: { appenders: ['cheese'], level: 'info' } }
});
const logger = log4js.getLogger('cheese');
await next()
const end = Date.now()
const responseTime = end - start;
logger.info(`响应时间为${responseTime/1000}s`);
}
}
创建
/mi-log/index.js
文件,并增加如下代码:const logger = require("./logger")
module.exports = () => {
return logger()
}
修改
middleware/index.js
文件,并增加对 log
中间件的注册, 如下代码:const path = require('path')
const bodyParser = require('koa-bodyparser')
const nunjucks = require('koa-nunjucks-2')
const staticFiles = require('koa-static')const miSend = require('./mi-send')
// 引入日志中间件
const miLog = require('./mi-log')
module.exports = (app) => {
// 注册中间件
app.use(miLog())app.use(staticFiles(path.resolve(__dirname, "../public")))
app.use(nunjucks({
ext: 'html',
path: path.join(__dirname, '../views'),
nunjucksConfig: {
trimBlocks: true
}
}));
app.use(bodyParser())
app.use(miSend())
}
堆的总值 - heapTotal
实际使用的堆 - heapUsed
推荐阅读
- CSS|采用官方最简单的办法搭建vite+vue+ts开发项目框架
- 笔记|手机也有生产力,手把手教你用手机开发APP
- 构建千万级高可用企业级Node.js应用wumi
- 前端面试|【1.1w字】面试常问Javascript 事件循环、同步异步、宏微任务,彻底明白原来这么简单
- 构建千万级高可用企业级Node.js应用
- ECMAScript|JavaScript性能优化具体实现-第二篇
- 个人|作为一个前端开发工程师,你会怼人吗?
- 网络|【技术学习】一次Node.js站点渗透
- javascript|web前端必备的 JavaScript 基础知识梳理总结