Diese Präsentation wurde erfolgreich gemeldet.
Die SlideShare-Präsentation wird heruntergeladen. ×

Node.js在淘宝的应用实践

Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Nächste SlideShare
Berserk js
Berserk js
Wird geladen in …3
×

Hier ansehen

1 von 27 Anzeige

Weitere Verwandte Inhalte

Diashows für Sie (20)

Andere mochten auch (20)

Anzeige

Ähnlich wie Node.js在淘宝的应用实践 (20)

Weitere von taobao.com (20)

Anzeige

Aktuellste (20)

Node.js在淘宝的应用实践

  1. 1. Node 在淘宝的应用实 践 这些年,我们一起开发过的 Node.js By @ 朴灵 1
  2. 2. 关于我 连 IE6 都能 兼容的男 • CNode 社区 人 • 前端 at SAP for Mobile Web • 前端 at 淘宝数据产品部 2
  3. 3. 议程 • 我为什么要做 Node 开发 • 准备工作与作品 • Node.js 带来的新问题与如何逆袭 • 异步编程 • 缓存与内存 • Buffer • Node.js 在淘宝产品中的一点实践 3
  4. 4. 长达半天的欢乐 icons powered by morcha design 前端屌丝的坎坷路 4
  5. 5. Node 与前端的亲缘 5
  6. 6. Node 与前端的亲缘 6
  7. 7. 左手 HTML5 右手 Node.js • 熟知的 JavaScript 执行原理 / 事件循环 • 熟悉的 API 、事件、单线程、回调 • Ajax/ 异步 • 相比 HTML5 , Node 将开启更多的可能 性 7
  8. 8. 好奇心 & 满足感 • HTTP 协议栈:深入后端,反哺前端 • Status code • Cookie & Session • Request & Response • Web Framework • 高性能 JavaScript 平台 • 拓宽视野 8
  9. 9. Go, go, go!!! var http example.jsServer running at http://127.0.0.1:1337/res) { % node = require('http');http.createServer(function (req, 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
  10. 10. 作品 10
  11. 11. 全 JavaScript 堆栈的产 品 Connect WebGhost ITier Redis & MRedis MongoSkin Should 11
  12. 12. 前端工程师到 Web 工程 师 让女神青睐 如何摆脱前端屌丝的身份 结果重了 10 斤 12
  13. 13. 问题:异步协作 var proxy = new EventProxy(); proxy.all("template", "data", "l10n", render); • 嵌套还是并行? $.get("template", function (template) { // something $.get("template", function (template) { proxy.trigger("template", template); }); // something $.get("data", function (data) { $.get("data", function (data) { // something // something $.get("l10n", function (l10n) { proxy.trigger("data", data); }); // something render(template, data); $.get("l10n", function (l10n) { }); // something }); proxy.trigger("l10n", l10n); }); }); 13
  14. 14. 问题:异步还是同步 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 view = fs.readFileSync("../views/index.html", "utf8"); 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
  15. 15. 问题:缓存的使用 var map = {}; var get = function (key) { var LimitableMap = require('limitablemap'); return map[key]; }; map = new LimitableMap(1000); var map.set("key1", "key1"); var set = function (key, value) { map.get("key1"); map[key] = value; }; // 检查缓存 if (!get(key)) { // 从数据库或别的地方获取了对象后,放进缓存中 set(key, value); } 15
  16. 16. 问题: Session • V8 内存堆栈限制 • 分布式中, Session 需要共享 (Redis) • 重启应用不丢失 session • 多点 Redis ,备份容灾 16
  17. 17. // 正确的方法 var chunks = []; var size = 0; 问题: Buffer 对象 res.on('data', function (chunk) { chunks.push(chunk); size += chunk.length; }); var data = function () { res.on('end', ""; res.on('data', function (chunk) { var data = null; //简单且正确的方法 对象 chunk 是一个 Buffer //switch(chunks.length) { var bufferHelper = 隐藏的 toString () case += chunk;// new BufferHelper(); data 0: data = new Buffer(0); }) break; req.on("data", function (chunk) { case 1: data = chunks[0]; bufferHelper.concat(chunk); .on("end", function () { break; })// 对 data 转码 default: .on('end', function () { }); data = new Buffer(size); var html i= bufferHelper.toBuffer().toString(); for (var = 0, pos = 0, l = chunks.length; i < l; i++) { var chunk = chunks[i]; }); chunk.copy(data, pos); pos += chunk.length; } break; } 17
  18. 18. 问题: String 传输的性 能 • 7k 大小的静态文件,需做替换 • String ➛ Buffer • 缓存 Buffer , 4 倍性能提升 18
  19. 19. 问题:多核 CPU 的利 var cluster = require('node-cluster'); • 用 单线程与多核 CPU var master = new cluster.Master(); master.register(8080, 'app.js'); • 单线程因为异常退出? master.dispatch(); 负载均衡 多核利用 • 仿若熟悉的 Web Worker: 提升稳定 var http = require('http'); var cluster = require('node-cluster'); child_process var worker = new cluster.Worker(); • 进程与消息 var server = http.createServer(function (req, res) { // server }); worker.ready(function (socket) { server.emit('connection', socket); }); 19
  20. 20. 小结 • 异步编程问题? EventProxy 、 JScex 等 • 内存限制问题?第三方存储 Redis • CPU 消耗问题?缓存中间结果 • 单线程 CPU 利用不足问题?多进程 • 单线程稳定性问题? Node-Cluster 20
  21. 21. 实践:运维 // 异步方法中 try catch 是不靠谱 • 异常 滴 双机房 进程数量 // 异步方法的异常 • 日志 双 Redis MRedis 模块 CPU async(functionMongoSkin { 双 MongoDB 内存if (err) { (err, data) • 监控 数据源集群 Loadlogger.error(err); 磁盘 IO // TODO return; • 部署 流量} // TODO • 备份容灾 }); 21
  22. 22. 实践:测试 • 测试 • 单元测试 • 自动化测试 • 性能测试 Should.js • 持续集成 WebGhost 22
  23. 23. 实践: CommonJS & Node & NPM CommonJS NPM Node 23
  24. 24. 实践:公司范围内共享代码 • 如何保护隐私代码 • 如何重用散乱代码 • 如何告别复制粘贴 24
  25. 25. 实践:公司范围内共享代码 单向同步 本地 NPM 官方 NPM 私有模块 项目 公有模块 25
  26. 26. 展望 • 深度发掘前端开发和用户体验 • 无需与开发沟通,节省成本 • 知晓细节,更易改进产品体验 • 感谢伟大的 github • 感谢伟大的 NPM 促成的生态圈 • 感谢 Node 这件美妙的礼物 26
  27. 27. Q&A 屌丝のぎゃくしゅ う 27

×