下栽地止:
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));
这将会在控制台产生如下后果:
{
rss: 4935680,
heapTotal: 1826816,
heapUsed: 650472
}
正如咱们所看到的,垃圾收集是个非常复杂的过程,并且即便代码没有问题也有可能会导致内存透露。通过应用 v8(和 chrome 开发者工具)提供的一些开箱即用的性能,可能帮忙咱们定位问题的源头,如果你将这种机制构建到你的利用内,这将会十分有助于你发现和修复问题。
当然,如果你问我下面的代码如何修复,其实十分的简略,只有在函数的最初加上一行 theThing = null; 即可。
构建千万级高可用企业级 Node.js 利用实战 – 日志治理
装置 log4js
模块
npm i log4js -S
<br/>
log4js
官网简略示例
在 middleware/
目录下创立 mi-log/demo.js
,并贴入官网示例代码:
var log4js = require('log4js');
var logger = log4js.getLogger();
logger.level = 'debug';
logger.debug("Some debug messages");
<br/>
而后在 /middleware/mi-log/
目录下运行:
cd ./middleware/mi-log/ && node demo.js
<br/>
能够在终端看到如下输入:
[2017-10-24 15:45:30.770] [DEBUG] default - Some debug messages
一段带有日期、工夫、日志级别和调用 debug
办法时传入的字符串的文本日志。实现了简略的终端日志输入。
<br/>
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.');
<br/>
再次在 /middleware/mi-log/
目录下运行:
node demo.js
<br/>
运行之后,在以后的目录下会生成一个日志文件 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.
留神: 日志文件产生的地位就是以后启动环境的地位。
<br/>
剖析以上代码就会发现,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`);
}
}
<br/>
创立 /mi-log/index.js
文件,并减少如下代码:
const logger = require("./logger")
module.exports = () => {return logger()
}
<br/>
批改 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