Node.js多进程服务原理&实践

content

  • 背景
  • 技术原理
  • 业务实践

背景

Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.an asynchronous event-driven JavaScript runtime

——nodejs.org

  • single thread.
  • non-blocking I/O.

why NIO?(相对BIO)

  • 场景
    • 适合I/O密集型应用
  • 写法
    • 无需处理data race问题
    • 新范式(发布订阅,callback,promise)
  • 性能
    • 节省线程开销
      • 线程调度开销
      • 线程内存开销
    • 并发数不受线程约束
    • 使用更高效的系统调用(epoll)

NIO也需要多进程(线程),why?

性能

使用多个进程,尽可能压榨机器性能(且很少有单核实例)

安全

在多进程中,所有进程同时挂实例才挂,稳定性数量级提高

趋势

单核瓶颈 -> 多核

单机瓶颈 -> 集群

  • Node.js: core core - 1
  • Netty: core * 2

Node.js多进程(线程)方案

  • worker_threads
  • cluster

child_process,介于上述两者之间,不常用

这次主题是多进程服务,下面详细讲下cluster的工作流程

Node.js cluster模块

  • 模块基础
  • 原理浅析

文档介绍

Node.js 的单个实例在单个线程中运行。 为了利用多核系统,用户有时会想要启动 Node.js 进程的集群来处理负载。

集群模块可以轻松创建共享服务器端口的子进程。

核心要点

面向场景:server

面向协议:tcp(http) & udp

两种算法:rr & share

RR算法三步走

  • 进程fork
  • server启动&worker注册
  • 连接分发

进程fork、server启动&worker注册

连接分发

RR算法(1)

RR算法(2)

Share算法

  • 一种简单的方式:
    • 直接发送server handle到worker
    • 无须调度,各个进程直接抢占&标记
  • udp(no rr),win32
  • 其他平台可选 NODE_CLUSTER_SCHED_POLICY=none
  • 负载均衡平均程度低于RR策略
  • 性能无明显区别

算法选择(1)

算法选择(2)

小结

  • server ✅,client ❎
  • 网络层 ✅,应用层 ❎
  • 底层能力 ✅,prodReady ❎

Node.js官方通过cluster模块提供了多进程服务的底层能力。在多进程的场景下,容错能力提高的同时,出错概率也潜在的大大提高,这时候需要社区的其他优秀工具来帮助开发者在生产环境更好的部署多进程服务。下面详细讲

Node.js 多进程prod方案

  • “旧社会”:虚拟机 + pm2
  • “新时代”:容器化 + 微服务(简介)

PM2

  • 基本用法
  • 基本原理
  • 优势与问题

其他功能

  • cluster mode(tcp)
  • graceful reload
  • startup script
  • key metrics monitor

启动流程、核心进程

关键技术列举 1)子进程启动

  • fork mode:child_process.spawn
  • cluster mode:cluster.fork(仅node)
  • 使用cluster.setupMaster替换fork文件

关键技术列举 2)processContainer

  • interpretor是node需要ProcessContainer
  • 无感知套壳:封装pm2的runtime端逻辑
    • key metric monitor
    • uncaughtXXX handle
    • pre-compile hooks

无感知套壳

node源码中的方法定义:

在ProcessContainer中:

关键技术列举 3)重启自启动

  • startup,save,resurrect
  • 根据环境,选择模板,生成/保存/运行脚本
  • 可开启自动save

生成的自启动文件

mac平台自启动模板

保存的所有进程信息

关键技术列举 4)graceful reload

优势和问题

  • 优势
    • 社区成熟
    • 丰富场景开箱即用
  • 问题
    • 属于“高级”方案
      • 用一个node守护另一个node
      • 对于“底层”问题的冲击无可奈何
    • 可用性未到极致
      • 实际场景中deamon很难被干掉
    • 时代局限性
      • 更适用于物理机&虚拟机场景
      • 不太适用于更现代的微服务体系

“底层”问题冲击

容器化&微服务简介

  • docker-compose:单机水平多实例扩展
  • k8s:分布式集群

https://www.cnblogs.com/JulianHuang/p/12568814.html

docker-compose:单机水平多实例扩展

https://www.cnblogs.com/JulianHuang/p/12568814.html

docker-compose:单机水平多实例扩展

k8s:分布式集群

https://kubernetes.io/docs/tutorials/kubernetes-basics/

讨论时间

deck

By shaomingquan

deck

  • 244