Weitere ähnliche Inhalte Ähnlich wie D2_Node在淘宝的应用实践 (20) Mehr von Jackson Tian (9) D2_Node在淘宝的应用实践6. 于我
连
• CNode社区 IE6都能兼容的
• 前端 at SAP for Mobile Web
• 前端 at 淘宝数据产品部
2
9. 议程
• 我为什么要做Node 发
• 准备工作与作品
3
10. 议程
• 我为什么要做Node 发
• 准备工作与作品
• Node.js带来的新问题与如何逆袭
• 步编程
• 缓存与内存
• Buffer
3
11. 议程
• 我为什么要做Node 发
• 准备工作与作品
• Node.js带来的新问题与如何逆袭
• 步编程
• 缓存与内存
• Buffer
• Node.js在淘宝产品中的一点实践
3
18. 长达半天的欢乐
icons powered by morcha design
前端屌丝的坎 路
4
31. 好奇心 & 满足感
• HTTP协议栈:深入后端,反哺前端
• Status code
• Cookie & Session
8
32. 好奇心 & 满足感
• HTTP协议栈:深入后端,反哺前端
• Status code
• Cookie & Session
• Request & Response
8
33. 好奇心 & 满足感
• HTTP协议栈:深入后端,反哺前端
• Status code
• Cookie & Session
• Request & Response
• Web Framework
8
34. 好奇心 & 满足感
• HTTP协议栈:深入后端,反哺前端
• Status code
• Cookie & Session
• Request & Response
• Web Framework
• 高性能JavaScript平台
8
35. 好奇心 & 满足感
• HTTP协议栈:深入后端,反哺前端
• Status code
• Cookie & Session
• Request & Response
• Web Framework
• 高性能JavaScript平台
• 拓宽视野
8
39. Go, go, go!!!
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello Worldn');
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');
9
41. Go, go, go!!!
% node example.js
Server running at http://127.0.0.1:1337/
9
65. 问题: 步协作
• 嵌套还是并行?
$.get("template", function (template) {
// something
$.get("data", function (data) {
// something
$.get("l10n", function (l10n) {
// something
render(template, data);
});
});
});
13
67. 问题:
var proxy = new EventProxy();
步协作
•
proxy.all("template", "data", "l10n", render);
嵌套还是并行?
$.get("template", function (template) {
// something
proxy.trigger("template", template);
});
$.get("data", function (data) {
// something
proxy.trigger("data", data);
});
$.get("l10n", function (l10n) {
// something
proxy.trigger("l10n", l10n);
});
13
69. 问题: 步还是同步
var proxy = new EventProxy();
var status = "ready";
• 杂的 步编程
var _getFile = function (callback) {
proxy.once("template", callback);
if (status === "ready") {
fs.readFile("views/index.html", function (err, file) {
status = "pending";
proxy.fire("template", err, file);
});
}
};
var _template;
var getTemplate = function (callback) {
if (_template) {
callback(null, _template);
} else {
_getFile(function (err, file) {
if (!err && !_template) {
_template = file.toString();
}
callback(null, _template);
});
}
};
14
71. 问题: 步还是同步
• 杂的 步编程
var view = fs.readFileSync("../views/index.html", "utf8");
14
72. 问题: 步还是同步
• 杂的 步编程
var view = fs.readFileSync("../views/index.html", "utf8");
同步 + 缓存,妥妥滴
14
74. 问题:缓存的使用
var map = {};
var get = function (key) {
return map[key];
};
var set = function (key, value) {
map[key] = value;
};
// 检查缓存
if (!get(key)) {
// 从数据库或 的地方获取了对象后,放进缓存中
set(key, value);
15
76. 问题:缓存的使用
var LimitableMap = require('limitablemap');
var map = new LimitableMap(1000);
map.set("key1", "key1");
map.get("key1");
15
83. 问题:Buffer对象
var data = "";
res.on('data', function (chunk) {
// chunk是一个Buffer对象
data += chunk;// 隐藏的toString()
})
.on("end", function () {
//对data转码
});
17
85. // 正 的方法
var chunks = [];
var size = 0;
问题:Buffer对象
res.on('data', function (chunk) {
chunks.push(chunk);
size += chunk.length;
});
res.on('end', function () {
var data = null;
switch(chunks.length) {
case 0: data = new Buffer(0);
break;
case 1: data = chunks[0];
break;
default:
data = new Buffer(size);
for (var i = 0, pos = 0, l = chunks.length; i < l; i++) {
var chunk = chunks[i];
chunk.copy(data, pos);
pos += chunk.length;
}
break;
}
17
});
87. 问题:Buffer对象
// 简单且正 的方法
var bufferHelper = new BufferHelper();
req.on("data", function (chunk) {
bufferHelper.concat(chunk);
})
.on('end', function () {
var html = bufferHelper.toBuffer().toString();
});
17
95. 问题:多核CPU的利用
• 单线程与多核CPU
• 单线程因为 常退出?
• 仿若熟悉的Web Worker: child_process
19
96. 问题:多核CPU的利用
• 单线程与多核CPU
• 单线程因为 常退出?
• 仿若熟悉的Web Worker: child_process
• 进程与消息
19
97. 问题:多核CPU的利用
var cluster = require('node-cluster');
•
var master = new cluster.Master();
单线程与多核CPU
master.register(8080, 'app.js');
master.dispatch();
• 单线程因为 常退出?
• 仿若熟悉的Web Worker: child_process
• 进程与消息
19
98. 问题:多核CPU的利用
var cluster = require('node-cluster');
•
var master = new cluster.Master();
单线程与多核CPU
master.register(8080, 'app.js');
master.dispatch();
• 单线程因为 常退出?
var http = require('http');
• 仿若熟悉的Web Worker:
var cluster = require('node-cluster'); child_process
• server = http.createServer(function (req, res) {
var worker = new cluster.Worker();
var
进程与消息
// server
});
worker.ready(function (socket) {
server.emit('connection', socket);
}); 19
99. 问题:多核CPU的利用
var cluster = require('node-cluster');
•
var master = new cluster.Master();
单线程与多核CPU
master.register(8080, 'app.js');
master.dispatch();
• 单线程因为 常退出? 负载均衡
var http = require('http'); 多核利用
• 仿若熟悉的Web Worker:
var cluster = require('node-cluster'); child_process
• server = http.createServer(function (req, res) {
var worker = new cluster.Worker();
var
进程与消息
// server
});
worker.ready(function (socket) {
server.emit('connection', socket);
}); 19
101. 小结
• 步编程问题?EventProxy、JScex等
20
109. 实践:运维
• 常 // 步方法中try catch是不靠谱滴
• 日志 // 步方法的 常
async(function (err, data) {
if (err) {
logger.error(err);
return; // TODO
}
// TODO
21
116. 实践:运维
• 常
• 日志 双机房
双Redis MRedis模块
• 监控 双MongoDB MongoSkin
• 部署
• 备份容灾
21
127. 实践:测试
• 测试
• 单元测试
• 自动化测试
Should.js
• 性能测试
WebGhost
• 持续集成
22
160. 展望
• 深度发掘前端 发和用户体验
• 无需与 发沟通,节省成本
• 知晓细节,更易改进产品体验
• 感谢伟大的github
• 感谢伟大的NPM促成的生态圈
• 感谢Node这件美妙的礼物
26