深入浅出Node.js 的读书笔记

深入浅出Node.js 的读书笔记

第一章 Node简介

简单介绍了一下node的历史09年/Ryan Dahl和特点异步IO,结构等等

第二章 模块机制

  • CommonJS的规范 引用规范require、定义exports.xx、标识等
  • 模块实现 模块加载顺序缓存-核心-文件文件定位顺序**.js-.json.node** 核心模块是用C/C++编写的
  • 包和npm 包其实就是一些人写的实现某些功能的代码集合package.json、bin等等文件在里面 npm就是下载这些包的工具,很方便,但是也有问题,代码参齐不全,可以通过github的星来判断好坏
  • 前后端共用模块 其实就是都是用一种语言来写前后端,所以就比较方便的意思

第三章 异步I/O

  • 为什么要用异步I/O 我之前是写php的,就是没有并发,有时候就很不爽,node的异步就可以用于并发,多个请求的时间从M+N->Max(M,N)
  • 现状 比较阻塞I/O和非阻塞I/O
  • Node的异步I/O 事件循环进程启动的时候不断去看有没有事件Tick需要处理
  • 事件驱动与高性能服务器

第四章 异步编程

  • 函数式编程 高阶函数把函数当参数和返回值 function foo(x, bar) { return bar(); }
  • 异步编程的优势和缺点 优势就是资源分配好,缺点就是对于异常的处理、嵌套过深、没有sleep、多线程对于写代码的也需要适应
  • 异步编程的解决方案 发布/订阅模式 Promise/Deferred模式其实就是jquery里面的ajax方法,有success和error、complete等 流程控制库next、async
  • 异步并发控制 bagpip通过设定限制来阻止过多的并发

内存控制

V8在64位下面只可以使用最多1.4G的内存,很少,所以内存的控制是很有必要的

  • V8的垃圾回收机制 分代式垃圾回收机制新生代内存优先回收,老生代的基本不回收,存在各种回收算法 Scavenge算法:简单来说就是分为from区和to去,回收的时候检查from有哪些是存活的,丢到to那边去,然后交换两个区,最后再清空原from,但是这个办法太浪费空间了 Mark-Sweep & Mark-Compact算法:其实就是做标记,需要回收的时候回收标记好的,这种会引起碎片化的问题
  • 高效使用内存 大概说了一下作用域、闭包、主动释放delete
  • 内存指标 查看进程使用的内存占用:process.memoryUsage()、查看系统使用的内存占用:os.totalmem()/os.freemem()
  • 内存泄露 内存泄漏也称作“存储渗漏”,用动态存储分配函数动态开辟的空间,在使用完毕后未释放,结果导致一直占据该内存单元。直到程序结束。(其实说白了就是该内存空间使用完毕之后未回收)即所谓内存泄漏 不要随便就用内存做缓存、关注队列、排查node-heapdump、node-memwatch

理解Buffer

  • buffer结构 其实buffer可以简单理解为一个Array对象,可以操作字节,结构上就是C++和javascript的结合,最大8K,8K内为小对象 内存分配full、partial、empty
  • buffer的转化 字符串转buffer new Buffer(str,[encoding]) buffer转字符串 buf.toString([encoding],[start],[end])
  • buffer的拼接 因为外国人使用的是英文,在拼接上面有天然的优势,但是我们使用的是英文,所以必须小心处理这个问题,正确的办法应该是用数组保存所以buffer对象的长度,再用Buffer.concat()来拼接 var chucks = []; var size = 0; res.on('data', function(chuck) { chucks.push(chuck); size += chuck.length; }); res.on('end', function() { var buf = Buffer.concat(chucks, size); var str = iconv.decode(buf, 'utf8'); console.log(str); })
  • buffer和性能 其实buffer的转化在无时无刻进行着

网络编程

其实这一章并不能说说node里面的知识,而是开发web都需要的知识

  • TCP 创建TCP服务器和一些TCP事件
  • UPD 创建UPD服务器和一些UPD事件
  • HTTP HTTP请求 HTTP响应 HTTP事件
  • WebSocket
  • 网络服务与安全 TLS/SSL 其实就是一个服务器和客户端直接的认证,还有HTTPS证书等

构建Web应用

  • 基础功能 请求方法get/post/delete/put 路径解析HTTP_Parser
  • cookie 放在request.head里面
  • session 安全性,虽然是放在服务器,但是在是通过cookie来认证的,所以还是有危险性的,类似xss漏洞
  • 缓存
  • basic认证
  • 数据上传 表单数据:判断Content-Type:application/x-www-form-urlencoded JSON:Content-Type:application/json;charset=utf-8 XML:Content-Type:application/xml;charset=utf-8 附件上传:有分隔符,可以使用formidable模块来直接处理 内存限制:写方法对上传上来的大小做限制,超过则显示413 CSRF:跨站请求伪造,可以在表单数据里面添加一个csrf的认证字段
  • 路由解析 其实这个里面比较关键的就是静态文件的请求路由,一般在路由级别加到一层,这样就可以避免请求的时候都去扫描所有文件了
  • MVC 其实就是路由怎么去映射,这个express里面就做得不错
  • 中间件 一些每个请求都需要去申请的功能,例如log、session,用一些别人写好的代码片段来给我们实现
  • 页面渲染 就是告诉页面,我这里需要用什么类型来解析是html,txt,还是json 模板,我们有些数据是动态的,需要在页面展示的时候输出,这个时候就需要用到模板技术了,这里大概说了一下模板技术是怎么实现的,没认真看,我是直接用了ejs,express里面默认的模板技术

玩转进程

一开始介绍了一下进程的发展

  • 多进程架构 父进程复杂分配,子进程复杂具体的业务,自带的child_process就可以实现了,下面的代码就是创建了两个子进程在sub.js里面
	var cp = require('child_process');
	var child1 = cp.fork(__dirname + '/sub.js');
	var child2 = cp.fork(__dirname + '/sub.js');
	
	var server = require('net').createServer();
	server.on('connection', function(socket) {
	    socket.end('父句柄');
	});
	server.listen(1337, function() {
		child1.send('server',server);
		child2.send('server',server);
		server.close();
	})
  • 集群稳定之路 一个关键就是自动重启
	var fork = require('child_process').fork;
	var cpus = require('os').cpus();
	var limit = 10;
	// 时间单位
	var during = 60000;
	var restart = [];
	var isTooFrequently = function() {
	    // 记录重启时间
	    var time = Date.now();
	    console.log('现在的时间是:' + time);
	    var length = restart.push(time);
	    console.log('重启数组长度为:' + length);
	    if (length > limit) {
	        // 取出最后10个记录
	        restart = restart.slice(limit * -1);
	    }
	    // 长度不大于限制   and   最新一次重启时间和第一次重启时间直接的间隔不大于限定的时间
	    console.log('第一次启动和现在这一次的时间间隔为' + (restart[restart.length - 1] - restart[0]));
	    return restart.length >= limit && restart[restart.length - 1] - restart[0] < during;
	}
	
	
	var server = require('net').createServer();
	server.listen(1337);
	
	var workers = {};
	var createWorker = function() {
	    if (isTooFrequently()) {
	        console.log('不允许重启了');
	        process.emit('giveup', restart.length, during);
	        return;
	    }
	    var worker = fork(__dirname + '/worker.js');
	    worker.on('message', function(message) {
	        if (message.act === 'suicide') {
	            createWorker();
	        }
	    })
	    worker.on('exit', function() {
	        console.log('worker' + worker.pid + ' exited');
	        delete workers[worker.pid];
	    });
	    worker.send('server', server);
	    workers[worker.pid] = worker;
	    console.log('Create worker . pid:' + worker.pid);
	};
	
	// 循环创建
	for (var i = 0; i < cpus.length; i++) {
	    createWorker();
	};
	
	// 如果进程自己退出,就让所有的工作进程退出
	process.on('exit', function() {
	    for (var pid in workers) {
	        workers[pid].kill();
	    }
	})
```	
子进程
var http = require('http');
var server = http.createServer(function(req, res) {
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.end('headled by child,pid is ' + process.pid + '\n');
    throw new Error('throw exception');
});

var worker;
process.on('message', function(m, tcp) {
    if (m === 'server') {
        worker = tcp;
        worker.on('connection', function(socket) {
            server.emit('connection', socket);
        });
    }
});

process.on('uncaughtException', function(err) {
    process.send({ act: 'suicide' });
    // 停止接收新的连接
    worker.close(function() {
        // 所以已有连接断开后,退出进程
        process.exit(1);
    });
    setTimeout(function() {
        process.exit(1);
    }, 5000);
})
- Cluster模块
	更好的创建和管理进程
### 测试和项目工程化
这两章放在一起,其实是我没怎么仔细看,我现在对于Node的理解其实还是很基础,所以这些其实对于我现阶段也是意义不大。所以就不说了
### 总结
学习node说长不长说短不短也有几个月了,期间就基本就是在看书,没做太大的实践,其实这样不好,没有成就感,接下来是要思考自己做一个小项目了。

转载于:https://my.oschina.net/gcdong/blog/1120361

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值