Node作为中间层
Node现在大部分都是做中间层
Web | Node | Java |
==> ==>
可以做到以下几点,逐步进阶:
- 做路由,例如vue+node,也没有跨域问题
- 要SEO,可以做MPA,用Node+swig模板,甚至可以做DB
- 做SPA和MPA混用,为了SEO和首屏直出
- 使用nodejs做同构,如nuxt和next
换个角度说:
- node作为Proxy
- API调用路由
- 跨域
- 提高自由度,上线时间,不被后端block
- node作为同构层
- vue、react
- 后期甚至可以作为Docker独立服务
- 中间层提高内存限制,以及QPS
P.S 如果不用Node做中间层,可以将Vue和React打包成SSR bundle,给浏览器去渲染
异步与IO
NodeJs适合IO密集型而不适用CPU密集型
- NodeJS为什么是单线程,因为js能操作DOM,那么多个线程同时操作DOM就不知道应该采取哪一个线程的操作
- 完美的异步IO应该是应用程序发起非阻塞调用,无需通过遍历或者事件轮询
- windows下异步回调机制是iocp,Linux下是epool和kqueue等更多的,不同发行版不同
- Amdahl、Gustafson定律
EventLoop
Node的异步线程通常都会丢进EventLoop中然后给对应的机制进行处理(iocp,Linux的自定义线程池)
但是有几个特殊的API不会丢到EventLoop
- SetTimeout和Setinterval线程池不参与
- process.nextTick()实现类似setTimeout(function(){}, o);每次调用放入队列中,在下一轮循环中取出
- SetImmediate();比process.nextTick()优先级低
- Node如何实现一个sleep(利用Promise和setTimeout)
常用的Node控制异步技术手段
按照历史时间顺序,1中早期的技术现在基本都被替代了
- Step、wind、Bigpipe、Q.js
- Async、Await
- Promise/Defferred是一种先执行异步调用,延迟传递的处理方式。Promise是高级接口,事件是低级接口。低级接口可以构建更多复杂的场景,高级接口是一旦定义,不太容易变化,不再有低级接口的灵活性,但对于解决问题非常有效
- 由于Node基于V8的原因,目前还不支持协程。协程不是进程或线程,其执行过程更类似于子例程,或者说不带返回值的函数调用
线程 vs 协程:
- 线程切换上下文由系统控制
- 协程切换上下文由自己控制
V8垃圾回收机制
V8的垃圾回收策略主要基于分代式垃圾回收机制。在自动垃圾回收的演变过程中,人们发现没有一种垃圾回收算法能够胜任所有场景。V8中内存分为新生代和老生代,新生代为存活时间较短对象,老生代为存活时间较长的对象。
目前V8采用了两个垃圾回收器,主垃圾回收器-Major GC(主要负责老生代的垃圾回收)和副垃圾回收器-Minor GC(Scavenger主要负责新生代的垃圾回收)。V8之所以使用两个垃圾回收器,主要是受到了代际假说的影响
关于Scavenger和Parallel垃圾回收等回收机制,这篇blog 说得很详细,先po在这,有时间的话再搬迁整理
需要补充一些的事MajorGC,在老生代的垃圾回收中,使用Mark-Sweep标记要清除的对象以及Mark-Compact压缩要保留的对象;另外用三色标记法标记对象,不,如下图
Node大规模站点部署
关于部署,接触过Java SSH或者IIS的多层架构,MVC等架构的应该能快速理解。这里也先贴上两张图,有时间的话再进行整理
补充几点
- Nagios实现服务器监控
- Varnish/Stupid 是Node作为中间层的cache,对Java等后端层的cache
- 同时为了减少中间层的开销,对后端的连接采用keep alivey以及heartbeat心跳检测