Node.js最佳实践

Node.js最佳实践

使用全局变量

1
2
3
4
5
6
7
global.CONSTANTS = constants;
global.E = E;
global.PID = process.pid;
global.WORKSPACE = __dirname;
global.TEMP = path.join(__dirname, '.temp');
global.APP_ID = uuid.v4();
global.NOOP = _.noop;
1
node -r global test.js

全局临时目录.temp & WORKSPACE

1
2
3
4
5
6
7
8
const mkdirp = require('mkdirp');
const path = require('path');

// init
(() => {
mkdirp.sync(path.join(__dirname, '.temp'));
mkdirp.sync(path.join(__dirname, 'logs'));
})();

二级缓存

lru-cache + redis

co-catch-next | promise.catch-next

1
2
3
co(function* () {
// ...
}).catch(next);
1
2
3
4
5
6
7
8
Q.fcall(promisedStep1)
.then(promisedStep2)
.then(promisedStep3)
.then(promisedStep4)
.then((value4) => {
// Do something with value4
})
.catch(next);

异常处理 catch-next & uncaughtException & domain

1
2
3
4
app.use(function(err, req, req, next) {
console.error(err);
res.send('HTTP-Internal Server Error');
});
1
2
3
4
5
6
process.on('uncaughtException', (err) => {
console.error(err);
db.stop(function(err) {
process.exit(1);
});
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var domain = require('domain');

module.exports = function (handler) {
return function domainMiddleware(req, res, next) {
var reqDomain = domain.create();

res.on('close', function () {
reqDomain.dispose();
});

reqDomain.on('error', function (err) {
if (typeof handler === 'function') {
handler(err, req, res, next);
} else {
next(err);
}
});

reqDomain.run(next);
};
};

退出程序

1
2
3
4
5
process.on('SIGINT', () => {
db.stop((err) => {
process.exit(err ? 1 : 0);
});
});

pm2.yml配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# pm2.yml
apps:
- script : './app.js'
name : 'app'
exec_mode: 'cluster'
instances: 'max'
watch : false
env :
NODE_ENV: local
env_vps:
NODE_ENV: vps
env_production:
NODE_ENV: production
log_date_format: 'YYYY-MM-DD HH:mm:ss Z'
combine_logs: true
merge_logs: true
error_file: './logs/pm2_app_err.log'
out_file: './logs/pm2_app_out.log'
autorestart: true
force: true

# pm2 start pm2.yml --env production

参考

【1】 【2】

本站采用「署名 4.0 国际」进行许可。