nodejs

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型,使其轻量又高效。V8引擎速度非常快,不用担心多线程,锁,并行计算产生的问题。
如果你编码不认真,java会给你丘,而nodejs会给你很多坑,使用WebStorm开发有的错误会报错,有的错误则会运行通过,产生意料之外的行为。

node擅长处理io密集型业务,在处理CPU密集计算的时候可选择以下方案:
1.node业务逻辑都以单线程进行处理,那如果其中包括耗时的复杂计算,可以以rpc 的方式让其他编译型语言处理,node 只负责搬运。 也就是说node负责接受请求、执行io、发送回复,其他逻辑由擅长计算的语言处理。
2.业务逻辑交给node,便于快速开发。其他内容交给其他语言,或者直接交给c++,用node-gyp编译一下。

Node.js Manual & Documentation
http://nodejs.cn/api/
http://shouce.qdfuns.com/nodejs/index.html

socket.connect参数顺序

创建TCP客户端的坑之connect的参数顺序是先port再host:

var net = require('net');
var HOST = '127.0.0.1';
var PORT = 8888;
var client = new net.Socket();
client.connect(PORT, HOST, function() {
    console.log('CONNECTED TO: ' + HOST + ':' + PORT);
    // 建立连接后立即向服务器发送数据,服务器将收到这些数据 
    client.write('message');
});

pm2

pm2 = P (rocess) M (anager)2,是可以用于生产环境的Nodejs的进程管理工具,它内置一个负载均衡,可以保证服务不会中断一直在线,并且提供0秒reload功能,还有其他一系列进程管理、监控功能。

pm2的安装和使用

npm install -g pm2
pm2 start app.js
pm2 save
pm2 startup
pm2 reload all
pm2 list
pm2 restart [id]

~# ls -a显示所有包括隐藏的文件,可以看到.pm2文件夹

更多pm2常用的命令用法介绍
http://i5ting.github.io/node-deploy-practice/
http://www.111cn.net/sys/linux/120062.htm
http://www.pangjian.info/2016/12/02/deploy-nodejs-pm2-1/?utm_medium=referral

缓存

nodejs通过文件名缓存加载过的模块,这里是全局缓存,不是页面内缓存。

grpc

安装grpc-tools
$ sudo npm install grpc-tools -g
把proto文件生成js文件
$ /usr/local/lib/node_modules/grpc-tools/bin/protoc --js_out=import_style=commonjs,binary:. --grpc_out=. --plugin=protoc-gen-grpc=/usr/local/lib/node_modules/grpc-tools/bin/grpc_node_plugin *.proto

不同操作系统平台下需要重新下载grpc,即重新执行 npm install grpc

http参数

参数名是区分大小写的,不存在的参数值是undefined
取get地址?后面的传参
var id=req.query.id;
取rest路径中的参数
var id = req.params.id;
取post时json对象中的参数
id=req.body.id;

http响应内容重写

router.get('/', function(req, res, next) {
    var content=getNowFormatDate();
    //重写,去掉了其它的头
    res.connection.write('HTTP/1.1 200 \r\n\r\n' + content, 'ascii', function(){
        res.connection.emit('end');
    });
    
    //res.send(content);
});

function getNowFormatDate() {
    var date = new Date();
    var seperator1 = "-";
    var seperator2 = ":";
    var currentdate = date.getFullYear() + seperator1 + addZero(date.getMonth() + 1) + seperator1 + addZero(date.getDate())
        + " " + addZero(date.getHours()) + seperator2 + addZero(date.getMinutes()) + seperator2 + addZero(date.getSeconds());
    return currentdate;
}

function addZero(num) {
    if (num >= 0 && num <= 9) {
        num = "0" + num;
    }
    return num;
}

express超时重复请求

3种解决办法
1.httpserver设置超时函数
var app = express();
var http = require('http');
var server = http.createServer(app);
server.on('timeout', onTimeout);
function onTimeout(err) {
}
2.加大超时时间
server.timeout=10*60*1000;
3.request或response设置超时处理方法
router.post('/xxx',function(req,res,next){
req.setTimeout(240000,function () {
});
}
http://blog.csdn.net/puncha/article/details/9378197

async

npm install async --save,其中--save参数会在工程package.json中dependencies中增加一条依赖;
async主要实现了三个部分的流程控制功能:
集合: Collections
流程控制: Control Flow
工具类: Utils

Nodejs异步流程控制Async


Async提供了很多针对集合的函数,简化对集合的异步操作步骤
https://my.oschina.net/chinacaptain/blog/469810

常用的流程控制:
series 串行,保证顺序,不依赖
parallel 并行
waterfall 依赖串行、瀑布流,之间需要传递结果时使用
auto 并行加依赖串行
apply 给函数预置第一个参数,然后返回一个新的函数。

async.series({
	one: function(callback){
		callback(null, 1);
	},
	two: function(callback){
		callback(null, 2);
	}
},function(err, results) {
	console.log(results);
});
或者
async.series([
            function(callback){
                callback(null, 1);
            },
            function(callback){
                callback(null, 2);
            }
        ],function(err, results) {
            console.log(results);
        });

socket超时

var socket = new net.Socket(); 创建后
socket.setTimeout(10 * 1000, function () {
if(!idle) {
console.log('timeout not idle');
if (callback) {
callback(false, {message: '请求超时'});
callback = null;
}
}else{
console.log('timeout idle');
}
});
不执行connect或write,10秒后会打印timeout idle。
等待9秒后再执行connect,如果connect很久,会在connect开始10秒后打印timeout not idle。
即创建socket和connect或write会开始新一轮超时计时。但不能多次设置settimeout,会引发emit数量警告。
idle为自定义的状态,在connect或wirte时设置idle=false。

安装最新稳定版本
https://segmentfault.com/a/1190000007542620

淘宝NPM镜像CNPM
http://npm.taobao.org/
npm install -g cnpm --registry=https://registry.npm.taobao.org

Promise

Promise.reduce 方法才是一个顺序执行 Promise 的方法,一些顺序执行的方法,比如 Promise.mapSeries 和 Promise.each ,都是基于 Promise.reduce 来实现的,这里的 reduce 和 Array.reduce 一样。

环境变量 get-env

#app.js中代码:
app.env = require('get-env')({
  init_env1:'init_env1',
  init_env2:'init_env2',
});

#根据以上代码,在命令行中调用时有效的NODE_ENV值有:dev,prod,init_env1,init_env2
export NODE_ENV=init_env1
node app.js 

传递参数

例如:node const-generate.js cx-kqy.txt
process.argv的值相当于是把整个命令按空格分割成字符串数组。

var arguments = process.argv.splice(2);
console.log('所传递的参数是:', arguments);
process.argv.forEach(function (val, index, array) {
    console.log(index + ': ' + val);
});

node端的缓存策略

如果缓存数据量不大,不需要多进程共享,可以node-cache方案或自己实现。如果需要多node.js进程共享并持久化,可以考虑用redis来实现,Redis的优势在于能够供多进程共享,有完善的备份和恢复机制。