• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Node.js在淘宝的应用实践
 

Node.js在淘宝的应用实践

on

  • 3,944 views

 

Statistics

Views

Total Views
3,944
Views on SlideShare
3,499
Embed Views
445

Actions

Likes
6
Downloads
45
Comments
0

3 Embeds 445

http://www.d2forum.org 434
http://www.itfeed.com 8
http://www.itfeed.cn 3

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Node.js在淘宝的应用实践 Node.js在淘宝的应用实践 Presentation Transcript

    • Node 在淘宝的应用实践这些年,我们一起开发过的 Node.jsBy @ 朴灵 1
    • 关于我 连 IE6 都能 兼容的男• CNode 社区 人• 前端 at SAP for Mobile Web• 前端 at 淘宝数据产品部 2
    • 议程• 我为什么要做 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 平台• 拓宽视野 8
    • 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 athttp://127.0.0.1:1337/); 9
    • 作品 10
    • 全 JavaScript 堆栈的产 品 ConnectWebGhost ITierRedis & MRedis MongoSkin Should 11
    • 前端工程师到 Web 工程 师 让女神青睐如何摆脱前端屌丝的身份 结果重了 10 斤 12
    • 问题:异步协作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
    • 问题:异步还是同步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
    • 问题:缓存的使用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
    • 问题: Session• V8 内存堆栈限制• 分布式中, Session 需要共享 (Redis)• 重启应用不丢失 session• 多点 Redis ,备份容灾 16
    • // 正确的方法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
    • 问题: String 传输的性 能• 7k 大小的静态文件,需做替换• String ➛ Buffer• 缓存 Buffer , 4 倍性能提升 18
    • 问题:多核 CPU 的利var cluster = require(node-cluster); • 用 单线程与多核 CPUvar master = new cluster.Master();master.register(8080, app.js); • 单线程因为异常退出?master.dispatch(); 负载均衡 多核利用 • 仿若熟悉的 Web Worker: 提升稳定var http = require(http);var cluster = require(node-cluster); child_processvar worker = new cluster.Worker(); • 进程与消息var server = http.createServer(function (req, res) { // server});worker.ready(function (socket) { server.emit(connection, socket);}); 19
    • 小结• 异步编程问题? EventProxy 、 JScex 等• 内存限制问题?第三方存储 Redis• CPU 消耗问题?缓存中间结果• 单线程 CPU 利用不足问题?多进程• 单线程稳定性问题? Node-Cluster 20
    • 实践:运维 // 异步方法中 try catch 是不靠谱• 异常 滴 双机房 进程数量 // 异步方法的异常• 日志 双 Redis MRedis 模块 CPU async(functionMongoSkin { 双 MongoDB 内存if (err) { (err, data)• 监控 数据源集群 Loadlogger.error(err); 磁盘 IO // TODO return;• 部署 流量} // TODO• 备份容灾 }); 21
    • 实践:测试• 测试 • 单元测试 • 自动化测试 • 性能测试 Should.js• 持续集成 WebGhost 22
    • 实践: CommonJS & Node & NPMCommonJS NPM Node 23
    • 实践:公司范围内共享代码• 如何保护隐私代码• 如何重用散乱代码• 如何告别复制粘贴 24
    • 实践:公司范围内共享代码 单向同步 本地 NPM 官方 NPM私有模块 项目 公有模块 25
    • 展望• 深度发掘前端开发和用户体验• 无需与开发沟通,节省成本• 知晓细节,更易改进产品体验• 感谢伟大的 github• 感谢伟大的 NPM 促成的生态圈• 感谢 Node 这件美妙的礼物 26
    • Q&A屌丝のぎゃくしゅ う 27