node 基本原理

BFF架构 background  for front

SSR 服务端渲染,为什么做服务端渲染呢,提高SEO,还有就是减少http请求,首屏加载慢的问题

node如何部署和nginx怎么连接,安全性怎么样

vue+node

1. 异步IO原理浅析

a. 异步IO的好处

前端通过异步IO可以消除UI的堵塞

IO是昂贵的,异步IO是更昂贵的,那不是减缓了速度了吗

NodeJS适用于IO密集型,而不是CPU密集型,Libuv做轮询,异步内存泄露

Libuv是nodejs的内部事件轮询机制,用来支持window和Linux

node接收请求后,将请求放到libuv中,libuv开启事件轮询 (event loop),轮询根据系统的不同启用不同的机制,Linux是Thread pool,windows是IOCP,事件完成后执行callback函数,将数据推送到前台,

cluster 和  fork 的区别

cluster是都是主的

fork是拷贝策略的

底层知识:
CPU的时钟周期,1/cpu主频   ->  1s/2.7 GHz,时钟周期指的是计算的时间间隔

2. 几个特殊的API

a. setTimeout 和setInterval不参与线程池

b. process.nextTick()实现类似,

c. setImmediate() 比process.nextTick()优先级低

d. Node如何实现一个sleep

async function test(){

  console.log('hello');

  await sleep(1000);

  console.log('world');

}

function sleep(ms){

  return new Promise(resolve => setTimeout(resolve,ms))

}

test();

3. 函数式编程在Node中的应用

高阶函数,将函数作为输入或者返回值,形成一种后续传递风格的结果接受方式,而非单一的返回值形式。后续传递风格的程序将函数业务重点从返回值传递到回调函数中。

app.use(function(){})

var emitter = new events.EventEmitter;

emitter.on('', function(){})

偏函数(柯里化),指定部分参数产生一个新的定制函数的形式就是偏函数。

就是生成一个函数,然后返回一个函数

var currying = function(fn) {
    // fn 指官员消化老婆的手段
    var args = [].slice.call(arguments, 1);
    // args 指的是那个合法老婆
    return function() {
        // 已经有的老婆和新搞定的老婆们合成一体,方便控制
        var newArgs = args.concat([].slice.call(arguments));
        // 这些老婆们用 fn 这个手段消化利用,完成韦小宝前辈的壮举并返回
        return fn.apply(null, newArgs);
    };
};

4. 常用的node控制异步技术手段

step、wind、bigpipe、Q.js

async await

promise/defferred是一种先执行异步调用,延迟传递的处理方式。promise是高级接口,事件是低级接口。低级接口可以构建更多复杂的场景,高级接口一旦定义不太容易变化,不再有低级接口的灵活性,但对于解决问题非常有效。

https://www.cnblogs.com/kazetotori/p/6043983.html

采用方法的先后顺序   async/await   promise   事件   回调函数

进程  一个应用程序是一个进程,进程可以有多线程

一个程序包含多个协程,就像一个进程包含多个线程。多个线程相对独立,有自己的上下文,切换受系统控制;而协程也相对独立,有自己的上下文,但是其切换由自己控制,由当前协程切换到其他协程由当前协程来控制。

https://www.cnblogs.com/kex1n/p/7425972.html

http://cnodejs.org/topic/58ddd7a303d476b42d34c911

协程我的理解,协程包含到线程里,一个线程包含多个协程,就是采用promise的异步操作就会生成一个协程。

5. node的内存管理和优化

a. v8垃圾回收机制

http://huang-jerryc.com/2016/04/14/NodeJS%E4%B8%AD%E8%A2%AB%E5%BF%BD%E7%95%A5%E7%9A%84%E5%86%85%E5%AD%98/

node使用内存是有限制的,这主要取决于v8的来源,64位系统能使用1.4G,32位系统是0.7G。当然这个也是可以配置的

在node启动的时候传入参数

node --max-nex-space-size=1024 app.js // 单位为KB
node --max-old-space-size=2000 app.js // 单位为MB
 
node采用的是分代式垃圾回收机制,分为新生代和老生代
新生代,存放新定义的变量,使用的是Scavenge算法,算法的过程:
scavenge算法中将新生代分为两个部分,每一部分叫semispace(半空间),这两个半空间中,只有一个处于使用状态,from空间和to空间,from处于使用状态,to处于闲置状态。变量定义后会存放到from空间,当进行垃圾回收时会检查from空间中存活的对象,这些存活的对象将被复制到to空间,没有用到的则释放,然后将to和from互换,简言之,新生代的垃圾回收,就是将存活的对象在两个semispace之间进行复制。
 
老生代存放的是一直使用的变量。当新生代垃圾回收时,即从from复制变量到to时,有两种情况会直接放到老生代,1. 如果to的占有率超过25%时,则直接将变量晋升到老生代,2. 如果变量经历过垃圾回收了,则直接晋升到老生代。这样to空间就会少,to和from交换时就会不同了。
老生代的垃圾回收机制,现在应该是增量回收(还是说是需要自己配置的?)
目前是mark-sleep算法和mark-compact算法相结合的方式进行垃圾回收。就是标记整理后,将活着的对象往一端移动,清除掉不用的空间,这样内存就不是碎片化的了,就可以存放大的数据了。这两种算法是怎么结合的呢,由于mark-compact需要移动对象,所以它会影响速度,正常情况下采用的是mark-sleep算法,只有在剩余空间不足以分配从新生代过来的对象时才进行mark-compact算法
 
鉴于node是单线程的,所以垃圾回收会阻塞代码的进行,因此就有增量回收机制,就是从标记开始,将之前一口气标记完成的操作改为增量标记,拆分成很多小步进,每完成一步进,就让程序执行一会,垃圾回收与应用程序这样交替进行,直到标记阶段完成。那整理和清理的过程呢,还是说标记用的时间最多。
 
V8后续还引入了延迟清理(lazy sweeping)与增量式整理(incremental compaction),让清理与整理动作也变成增量式的。同时还计划引入并行标记与并行清理,进一步利用多核性能降低每次停顿的时间
 
内存泄露的抓取工具
b. 常见的内存泄露
无限增长的数组
无限制设置属性和值
任何模块内的私有变量和方法均是永驻内存的,需要将不用的模块设为null
大循环,无GC机会 
 
6. node集群的应用
a. 预备上线
b. pm2 是一个带有负载均衡功能的node应用的进程管理器 
服务器集群
 
 
UV(unique visitor)
一天内一个访客(通过身份验证确定为同一人)多次访问只计算一次
IP
一天内相同的ip只被计算一次
PV(page visitor)
打开页面计算一次
VV(Visit View)
访问网站的次数,打开网站算一次,浏览页面不算。
 
 
 
 
 

猜你喜欢

转载自www.cnblogs.com/wenwenli/p/8762207.html