Node在淘宝的应用实践这些年,我们⼀一起开发过的Node.jsBy @朴灵    1
关于我                             连IE6都能兼• CNode社区                     容的男人• 前端 at SAP for Mobile Web• 前端 at 淘宝数据产品部        ...
议程• 我为什么要做Node开发• 准备工作与作品• Node.js带来的新问题与如何逆袭 •   异步编程 •   缓存与内存 •   Buffer• Node.js在淘宝产品中的⼀一点实践               3
长达半天的欢乐       icons powered by morcha design前端屌丝的坎坷路           4
Node与前端的亲缘     5
Node与前端的亲缘     6
左手HTML5右手Node.js• 熟知的JavaScript执行原理/事件循环• 熟悉的API、事件、单线程、回调• Ajax/异步• 相比HTML5,Node将开启更多的可能性            7
好奇心 & 满足感• HTTP协议栈:深入后端,反哺前端 •   Status code •   Cookie & Session •   Request & Response •   Web Framework• 高性能JavaScript平...
Go, go, go!!!var http example.js% node = require(http);Server running at http://127.0.0.1:1337/http.createServer(function ...
作品 10
全JavaScript堆栈的产品                               ConnectWebGhost                     ITierRedis & MRedis                 Mon...
前端工程师到Web工程师           让女神青睐如何摆脱前端屌丝的身份           结果重了10斤      12
问题:异步协作var proxy = new EventProxy();•proxy.all("template", "data", "l10n", render);    嵌套还是并行?$.get("template", function (...
问题:异步还是同步var proxy = new EventProxy();var status = "ready";• 复杂的异步编程var _getFile = function (callback) {  proxy.once("temp...
问题:缓存的使用var map = {};var get = function (key) {var LimitableMap = require(limitablemap);  return map[key];}; map = new Lim...
问题:Session• V8内存堆栈限制• 分布式中,Session需要共享(Redis)• 重启应用不丢失session• 多点Redis,备份容灾             16
// 正确的方法var chunks = [];var size = 0;         问题:Buffer对象res.on(data, function (chunk) {  chunks.push(chunk);  size += chu...
问题:String传输的性能• 7k大小的静态文件,需做替换• String ➛ Buffer• 缓存Buffer,4倍性能提升          18
问题:多核CPU的利用var cluster = require(node-cluster);• 单线程与多核CPUvar master = new cluster.Master();master.register(8080, app.js);...
小结• 异步编程问题?EventProxy、JScex 等• 内存限制问题?第三方存储Redis• CPU消耗问题?缓存中间结果• 单线程CPU利用不足问题?多进程• 单线程稳定性问题?Node-Cluster             20
实践:运维• 异常     // 异步方法中try catch是不靠谱滴         双机房         // 异步方法的异常         进程数量• 日志     双Redis MRedis模块         async(fun...
实践:测试• 测试    •   单元测试    •   自动化测试    •   性能测试         Should.js•   持续集成                         WebGhost                22
实践:CommonJS & Node & NPMCommonJS           NPM           Node             23
实践:公司范围内共享代码• 如何保护隐私代码• 如何重用散乱代码• 如何告别复制粘贴         24
实践:公司范围内共享代码         单向同步 本地NPM          官方NPM私有模块     项目      公有模块           25
展望• 深度发掘前端开发和用户体验• 无需与开发沟通,节省成本• 知晓细节,更易改进产品体验• 感谢伟大的github• 感谢伟大的NPM促成的生态圈• 感谢Node这件美妙的礼物         26
Q&A屌丝のぎゃくしゅう            27
Upcoming SlideShare
Loading in …5
×

D2_node在淘宝的应用实践_pdf版

3,228 views
3,087 views

Published on

Published in: Technology, Business
2 Comments
6 Likes
Statistics
Notes
No Downloads
Views
Total views
3,228
On SlideShare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
37
Comments
2
Likes
6
Embeds 0
No embeds

No notes for slide

D2_node在淘宝的应用实践_pdf版

  1. 1. Node在淘宝的应用实践这些年,我们⼀一起开发过的Node.jsBy @朴灵 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.js% node = require(http);Server running at http://127.0.0.1:1337/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
  10. 10. 作品 10
  11. 11. 全JavaScript堆栈的产品 ConnectWebGhost ITierRedis & 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);varmap.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 = "";res.on(end, function () {res.on(data, function (chunk) { var data = null;//switch(chunks.length) { // chunk是⼀一个Buffer对象 简单且正确的方法 data 0: data = new =隐藏的toString() case += chunk;//Buffer(0);var break; bufferHelper new BufferHelper();}) case 1: data = functionreq.on("data",chunks[0]; (chunk) {.on("end", function () { bufferHelper.concat(chunk); break;})//对data转码 default:.on(end,new Buffer(size);}); data = function () { for (var i = 0, pos = 0, l = chunks.length; i < l; i++) { varvar chunk bufferHelper.toBuffer().toString(); html = = 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);• 单线程与多核CPUvar master = new cluster.Master();master.register(8080, app.js);master.dispatch(); 负载均衡• 单线程因为异常退出? 多核利用var http = require(http);• 提升稳定 仿若熟悉的Web Worker: child_processvar cluster = require(node-cluster);• 进程与消息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模块 async(function (err, data) { CPU 双MongoDB MongoSkin 内存 { if (err)• 监控 数据源集群 Loadlogger.error(err); 磁盘IO // TODO return;• 部署 流量} // TODO });• 备份容灾 21
  22. 22. 实践:测试• 测试 • 单元测试 • 自动化测试 • 性能测试 Should.js• 持续集成 WebGhost 22
  23. 23. 实践:CommonJS & Node & NPMCommonJS NPM Node 23
  24. 24. 实践:公司范围内共享代码• 如何保护隐私代码• 如何重用散乱代码• 如何告别复制粘贴 24
  25. 25. 实践:公司范围内共享代码 单向同步 本地NPM 官方NPM私有模块 项目 公有模块 25
  26. 26. 展望• 深度发掘前端开发和用户体验• 无需与开发沟通,节省成本• 知晓细节,更易改进产品体验• 感谢伟大的github• 感谢伟大的NPM促成的生态圈• 感谢Node这件美妙的礼物 26
  27. 27. Q&A屌丝のぎゃくしゅう 27

×