node.js开发实战

Posted 潮哥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了node.js开发实战相关的知识,希望对你有一定的参考价值。

1. 什么是RPC调用(远程过程调用)remote procedure call

半双工和全双工通信(实现难度和成本) 

二进制协议

. 更小的数据包体积

. 更快的编解码速率

2. Buffer 编解码二进制数据包 (node 的二进制Buffer模块)

#buffer创建
// 具体用法参见文档
1. Buffer.from()
2. Buffer.alloc()

var buffer = Buffer.from(\'guiqing\'); // <Buffer 67 75 69 71 69 6e 67>
var buffer = Buffer.from(\'股\'); //<Buffer e8 82 a1>
对于默认的utf-8编码;英文占用一个字节,中文占用三个字节,为16进制

#buffer的写入
buffer.writeInt8
buffer.writeInt16BE
buffer.writeInt16LE

为啥writeInt8没有大小端,是因为一个字节为8位,刚好不需要两位,没有顺序之分
原生动态将多个string转为二进制的话,可能还需要获取写入的string对应的字节长度,以便管理下一次写入的offset;
可以通过Buffer.byteLength()来获取

(Protocol Buffers)用来编码二进制数据

  protocol-buffers(npm包,用于方便实现编码二进制数据)

var obj = {
  a: 1
}
var buffer = Buffer.from(JSON.stringify(obj))
console.log(buffer.toString())// 可以将json数据直接这样转为二进制数据

3. net 搭建多路复用的RPC通道

 对应的https://github.com/geektime-geekbang/geek-nodejs/tree/master/chapter2/rpc

 4. HTTP 服务性能测试

压力测试工具(ab、webbench)

通常用ab (https://www.jianshu.com/p/43d04d8baaf7

找到性能瓶颈

. top (cpu、内存)

. iostat (硬盘)

5. Node.js性能分析工具

1⃣️ 自带的 profile  启动命令的时候带上--prof (eg. node --prof app.js)

这时会生成一个*.log 文件

可以通过命令: node --prof-process *.log > profile.txt  (生成文件, 然后主要看这里,看主要的耗时)

 2⃣️ Chrome devtool (eg. node --inspect-brk app.js)

chrome://inspect 进入

3⃣️ Clinic.js  

4⃣️ 内存分析,可以点击Memory

 

 这个就是你所占有的内存总量

6. 石头剪刀布游戏

1⃣️ process.argv

 

 

 可以获取到用户输入的指令参数

2⃣️ module.exports 和 exports的区别

#lib.js

exports.a = \'hello world\';

module.exports = function (){
  console.log(\'exports被重新赋值了,上面定义的属性获取不到\')
}

setTimeout(function(){
   console.log(exports); // {a: \'hello world\'}
}, 2000)


#index.js
const lib = require(\'./lib.js\'); // lib 是引用类型
console.log(lib); //[Function]

lib.b = \'我修改了对象\'

3⃣️ process.stdin

 7. callback 为啥采用error-first 模式

/**
 * try catch只能抓到一个调用堆栈内,即一个事件循环里的错误
 */
// try {
    interview(function (err, res) {
        if (err) {
            console.log(\'cry\')
            return;
        }
        console.log(\'smile\')
    })

// } catch (e) {
//     console.log(\'cry\')
// }



function interview(callback) {
    
    setTimeout(() => {
        if (Math.random() > 0.2) {
            callback(null, \'success\')

        } else {
            // throw new Error(\'fail\');
            callback(new Error(\'fail\'))
        }

    }, 500)
}

 8. promise 的状态是和最后一个then或者catch相关,或者是then中的其他promise状态相关

 

 

 9. koa的优势

1⃣️. 不绑定中间间,更简洁

2⃣️. 使用async/await实现中间件,有暂停的能力(await next());在异步的情况下也符合洋葱模型

10. 使用es6模版和vm作为渲染引擎

// template.js
const fs = require(\'fs\'); const vm = require(\'vm\'); const templateCache = {}; const templateContext = vm.createContext({ include: function (name, data) { const template = templateCache[name] || createTemplate(name) return template(data); } }); function createTemplate(templatePath) { templateCache[templatePath] = vm.runInContext( `(function (data) { with (data) { return \\`${fs.readFileSync(templatePath, \'utf-8\')}\\` } })`, templateContext ); return templateCache[templatePath] } module.exports = createTemplate

// 使用 index.js

const template = require(\'./template\');

const detailTemplate = template(__dirname + \'/template/index.html\');

app.use(async (ctx) => {

   ctx.status = 200;

   ctx.body = detailTemplate(result);
})

渲染引擎模版要提供

1⃣️ include 子模版

2⃣️ 具备防止xss攻击,helper函数

11. graphQL: Facebook开发的实现API服务的库

比Restful的优势在于能够让前端有“自定义查询”数据的能力

koa-graphql(npm包)

12. 前后端同构

场景:服务端渲染,同时前端可以进行无刷新排序和分类等操作

难点:由于我们使用redux或者vuex; 所以数据方面比较难同构, react 可以用 next.js 进行服务端渲染

axios支持运行在浏览器和node.js

 13. 子进程(child_process)和 工作线程(worker_threads)和集群(cluster)

# child_process.fork() 方法是 child_process.spawn(), 能和父进程进行通信
# index.js
const cp = require(\'child_process\');

const child_process_demo = cp.fork(__dirname + \'/child.js\');

child_process_demo.send(\'hello\');

#child.js
process.on(\'messaage\', function(str) {
   console.log(str);
   process.send(\'world\'); // process是全局变量, 且为当前子进程全局变量,所以只会接收到child_process_demo的消息
})
const cluster = require(\'cluster\');
const os = require(\'os\');

if (cluster.isMaster) {
    for(let i = 0; i < os.cpus().length / 2; i++) {
        cluster.fork();
    };
} else {
    require(\'./app.js\');
};

//子进程启动的时候也会执行这个文件,并且isMaster是false
// cluster 启动多个子进程,但是能监听同个端口是进行了处理的。
// 处理成类似server.listen({fd: 7});这里不太清楚没细究

14. 反向代理和缓存服务 (nginx)

 

 15. serverless (渐进式)

 云函数(自行百度理解)

const fs = require(\'fs\');
const mkdirp = require(\'mkdirp\');
const webpack = require(\'webpack\');
const mfs = new (require(\'memory-fs\'));

module.exports = function (
    businessName,
    dataJSPath,
    templatePath
) {
    mkdirp.sync(__dirname + \'/../business/\' + businessName);

    fs
        .createReadStream(templatePath)
        .pipe(fs.createWriteStream(__dirname + \'/../business/\' + businessName + \'/template.tpl\'));

    const compileTask = webpack({
        mode: \'development\',
        devtool: false,
        target: \'node\',

        entry: dataJSPath,

        module: {
            rules: [
                { test: /.proto$/, use: \'text-loader\' }
            ]
        },

        output: {
            path: "/whatever",
            filename: "data.js"
        }
    });

    compileTask.outputFileSystem = mfs; // 这里可以借鉴,将webpack打包出来的文件先存在内存

    compileTask.run(function(err) {
        if (err) { return }
        const content = mfs.readFileSync(\'/whatever/data.js\')
        fs.writeFileSync(__dirname + \'/../business/\' + businessName + \'/data.js\', content);
    })
}

 

 

以上是关于node.js开发实战的主要内容,如果未能解决你的问题,请参考以下文章

Node.js开发实战详解的内容体系

Node.js JavaScript 片段中的跳过代码

Vue.js+Node.js全栈开发入门实战 | 推荐

iKcamp新书上市《Koa与Node.js开发实战》

iKcamp新书上市《Koa与Node.js开发实战》

图书Koa与Node.js开发实战