Node

:::info 📦 基于 Node.js 14.x LTS 版本 :::

basic and intro.

Node 的特点

Strength

  • Asynchronized I/O
  • Events and Callbacks
  • Single -Thread
  • Multi-platforms Support

Weakness

  • 不擅长 CPU 密集型任务
  • 无法更好地运用多核处理器
  • 单线程的健壮性问题(遇到错误会导致整个程序退出)
  • 异步程序测试不是那么容易

应用场景

  • I/O 密集型
  • 数据中介
  • 服务端工具
  • JS 全栈

Node and Modules

CommonJS 规范

require/define/exports 的运行:

  1. (function (exports, require, module, __filename, __dirname) { // The code we write will be here});
  2. var http = require('http');
  3. http.newMethod = function () {};
  4. module.exports = http;

Attention: Under the hood in the Node module system, the result of require is cached after the first time it’s called for a specific module. This means multiple calls to require('./mmm') will always return the same instance of the mmm module.

Node 模块的实现

Node模块分为两类:核心模块(已经编译好的二进制执行文件)和文件模块(运行时动态加载,需要进行路径分析、文件定位以及编译执行的过程,基于V8引擎)。

  • JS 文件:vm 原生模块的:runInThisContext() 方法执行,类似于 eval()
  • JSON 文件: JSON.parse() 的方式生成对象
  • C/C++ 文件: 利用 process.dlopen() 方法进行加载,并通过不同的抽象层次进行封装。

Node的模块,具有缓存优先加载的策略,编译和执行后的对象都会被缓存以提高效率。

  • 路径分析:递归到根目录去查询 node_modules 文件夹中是否有对应需要的模块。
  • 文件定位:.js .node .json 的顺序加载
  • 编译执行

编程范式

Async I/O

Node.js Async I/O

Async Patterns

Node.js Async Patterns

Node Core Modules

  • Buffer
  • Stream
  • File & I/O
  • OS
  • Process
  • Cluster
  • WorkerThread:多线程操作
  • Net: TCP or IPC servers
  • HTTP
  • HTTP/2
    • http.Server
    • http.Agent
    • http.createServer()
    • http.request(...)
  • HTTPS
  • UPD(dgram):UDP 协议相关 API
  • TLS(SSL):SSL 连接相关 API
  • DNS:DNS 查询相关 API
  • Crypto:加解密和证书、签名相关的 API
  • Zlib:Gzip 关联操作(压缩 / 解压缩)

Sever Side Programming

具体的实现代码我们可以参考 Express 等框架或者工具的部分源码来理解它们是如何运作的。

ME | 如果要真正学好 Node Web程序设计的话,有必要认真理解 Express 等架构和实现细节。当然,现在我更加推荐自己去认真阅读 https://eggjs.org/ 中对 WebFramework 的设计和实现。

基础功能

  • 请求方法
    • ServerRequest
    • ServerResponse
  • 路径解析和查询字符串
    • url.parse()
    • querystring.parse()
  • Cookie
    • parseCookie(req.headers.cookie)
  • Session
    • req.session 贴加在对应的 Cookie 中
    • 查询字符串的方式来实现
    • 考虑 Session 与 内存,以及安全的问题
  • 缓存技术
    • 添加 Expires 或 Cache-Control 到报文头中 If-Modified-Since / Last-Modified字段
    • 配置 ETags
    • 让 Ajax 缓存
  • Basic 认证

数据库

参考 MangoDB

数据上传

  • 表单数据: Content-Type: application/x-www-form-urlencoded, 对应 querystring.parse(req.rawBody) 方法获得请求数据
  • 其它格式 req.body 获得相关数据
  • 附件上传 Content-Type: application/form-data 对应使用对应的解析器执行
  • 数据上传和安全
    • 内存限制
    • 防止 Cross-Site Request Forgery CSRF 方法在于验证 token

路由解析

  • 文件路径
    • 静态文件
    • 动态文件(因为 Node 的服务脚本和业务脚本是一体的,所以不需要所谓的动态方式实现)
  • MVC
  • 实现方法
    • 基于正则的路由匹配
    • 进行剩余的参数解析
    • 自然映射
  • RESTful

Middleware 中间件

理解中间件的概念:用于简化和隔离基础设施与业务逻辑之间的细节,让开发者能够关注在业务上的开发,以达到提高开发效率的目的。

页面渲染

  • 内容响应
    • MIME响应 var mime = require('mime')
    • 附件下载
    • 响应JSON
    • 响应跳转
  • 视图渲染
  • 模板系统

Bigpipe 思路

先传输整个空白框架,再逐步向框架中填入数据。以此提高响应速度。

调试

  • 使用 node-debug app.jsnode inspector 进行调试。使用 Chrome 自带的 devTool 进行可视化界面的调试。
  • 使用 node debug app.js 即 node 自带的断点调试工具进行调试。参考 官方 API Doc

测试

编写可测试的代码的原则:

  • 单一职责
  • 接口抽象
  • 层次分离

单元测试

  • 断言:用于保证单元测试中最小单元是否正常的检测方法。
  • 测试框架:提供测试服务,但是本身不参与测试。e.g. mocha
  • 测试代码中的文件组织:将测试框架和服务模块加入 devDependencies 中声明,而测试代码,存放于 test 目录中
  • 测试用例配置应该规范、清晰合理。同时在异步测试的时候,需要配置好超时的情形。
  • 测试覆盖率
  • 私有方法、属性的测试:rewire 的思想
  • 考虑 工程工具自动化测试,提高效率,利用 Gulp 等工具。

性能测试

基准测试

  • benchmark 测试能够组织基准测试

压力测试

对:吞吐率、响应时间以及并发数等进行分析、测试。

利用:ab siege http_load 等工具来构造压力测试。

产品化

项目工程化

  • 可能的目录结构
    • 说明文件
      • README.md
      • History.md
      • INSTALL.md
    • Makefile
    • benchmark // 基准测试
    • lib // 没有模块化的项目
    • logs
    • config
    • bin
    • tools
    • doc // 文档
    • test // 测试
    • proxy // 数据代理
    • dispatch.js // 多进程管理
    • app
      • assets
      • assets.json // 静态文件和CDN路径的映射文件
      • view
      • controller
      • route
      • model
    • node_modules
  • 构建工具
  • 编码规范
  • 代码审查

部署流程

  • 部署环境:代码 —> Stage —> pre-release —> product
  • 部署操作:nohup node app.js & 以不挂断进程的方式进行
  • 利用 bash 脚本进行更为有效地管理

性能管理

  • 动静分离
  • 启用缓存
  • 多进程架构的配置 cluster 模块
  • 读写分离
  • … 还有非常多的优化建议需要自寻总结和理解 + 探索

日志

  • 访问日志
  • 异常日志
  • 日志处理:存储、分析和销毁。

监控报警

  • 日志监控
  • 响应时间、进程、磁盘、内存、CPU占用、CPU Load、I/O负载、网络监控
  • 应用状态监控
  • DNS监控

报警机制的实现:邮件机制(nodemailer 模块)、短信、电话等

稳定性

WIP

使用 Node 开发工具


Ref

公司内部: