Skip to content

11产品化

node要实际作为一款产品运用,要多方面考虑:部署、性能、日志、监控、多机器、容灾备份等,实际中工作量非常多 产品化

  • 1、工程化
    • 目录结构
    • 构建工具
      • Makefile make linux(过时)
      • Grunt 媲美 java Maven(过时)
      • webpack、vite
    • 编码规范
      • 一种是文档式的约定,
      • 一种是代码提交时的强制检查
      • JSLint和JSHint(过时)
      • eslint(目前)
    • 代码审查
      • gitlab
      • 代码提交以后,审查再合并
        • 功能是否正确完成、
        • 编码风格是否符合规范、(工具)
        • 单元测试是否有同步添加
  • 2、部署
    • 测试环境 stage

    • 预发布环境 pre-release

    • 生产环境 product

    • 部署操作

      • nohup node app.js &(以不挂断进程的方式执行)
      js
      var fs = require("fs");
      var path = require("path");
      var pidfile = path.join(__dirname, "run/app.pid");
      fs.writeFileSync(pidfile, process.pid);
      
      process.on("SIGTERM", function () {
        if (fs.existsSync(pidfile)) {
          fs.unlinkSync(pidfile);
        }
        process.exit(0);
      });
      • bash 脚本(11.2appctl.sh):实现应用的启动、 停止和重启等操作
  • 3、性能
    • 原则
      • 做专一的事。
      • 让擅长的工具做擅长的事情。
      • 将模型简化。
      • 将风险分离。
    • 方法
      • 动静分离
        • 图片、脚本、样式表和多媒体等静态文件放到专业的静态文件服务器上
        • 用Nginx或者专业的CDN来处理
        • 静态内容,直接进行Buffer传输可以很大程度上提升性能
      • 启用缓存
        • redis
        • 具体场景:高并发读取场景、热点数据缓存、数据计算结果缓存、会话管理
        • 启用redis带来了一些额外的复杂性:缓存一致性和缓存更新策略,需综合考虑
      • 多进程架构
        • cluster
        • pm、forever、pm2这样的模块用于进程管理
      • 读写分离
        • 读写分离,将数据库进行主从设计,这样读数据操作不再受到写入的影响
        • 有一个主数据库(Master)和一个或多个从数据库(Slaves)。
        • 所有的写操作都发送到主数据库,然后主数据库将写操作的日志传播给从数据库进行异步复制。
        • 读操作可以从任意一个从数据库中进行,从数据库是只读的,并且与主数据库保持同步
  • 4、日志
    • 访问日志
      • 中间件框架connect提供日志功能
    • 异常日志
      • console.Console 实现自己的日志对象
      • 每个开发者应当将API内部发生的异常作为第一个实参传递给回调函数
      • 回调函数中产生的异常, 则可以不用过问, 交给全局的uncaughtException事件去捕获即可
      • 异常尽量由最上层的捕获记录,底层只传递给上层
      • 还要记着对日志进行格式化处理
    • 日志文件/数据库(不推荐)
      • 日志记录可以在线写(日志消息写入本地文件或输出到控制台。这种方式可以提供实时的日志记录,)
      • 日志分析则可以借助一些工具同步到数据库中,通过离线分析的方式反馈出来(海量日志,日志分析工具同步到数据库,进行分析)
    • 分割日志
      • 按日期分割,保存,方便排查使用
  • 5、监控报警
    • 设置上限,一旦大的波动,发出警报
    • 监控
      • 5-1、日志监控
        • 异常日志的监控,按照异常类型、数量反应出来,
        • 子系统相关的反应子系统
        • QPS 检查业务在时间上的分布
        • pv uv 使用者们的习惯、 预知访问高峰等。
      • 5-2、响应时间
        • 可以在nginx方向代理上监控
        • 或者访问日志监控
        • 健康的应该是波动较小的、持续均衡的
      • 5-3、进程监控
        • 检查工作进程的数量,
        • 如果低于预估值, 就应当发出报警声。
      • 5-4、磁盘监控
        • 用量 一旦不够用各种问题
        • 设置一个上限, 一旦磁盘用量超过警戒值
        • 就整理日志、清理磁盘
      • 5-5、内存监控
        • 内存泄漏
        • 只升不降,肯定内存泄漏
        • 解决方法:多进程架构服务群,规定每个进程服务数量,满了,就启动新的,旧的逐次关闭
      • 5-6、CUP占用监控
        • 如果用户态CPU使用率较高, 说明服务器上的应用需要大量的CPU开销;
        • 如果内核态CPU使用率较高, 说明服务器花费大量时间进行进程调度或者系统调用;
        • IOWait使用率则反应的是CPU等待磁盘I/O操作。
        • 用户态小于70%、内核态小于35%且整体小于70%时,属于健康
      • 5-7、CUP load监控(CPU负载均衡)
        • 描述操作系统当前的繁忙程度,
        • CPU在单位时间内正在使用和等待使用CPU的平均任务数
        • 三个指标:1分钟的平均负载、 5分钟的平均负载、 15分钟的平均负载
        • CPU load过高说明:进程数量过多,可能用子进程模块反复启动新的进程。
      • 5-8、I/O负载 磁盘I/O
        • 磁盘上的读写情况,也应监控
      • 5-9、网络监控
        • 需要对流量进行监控并设置上限值
        • 超过警戒值, 开发者就应当找出流量增长的原因
        • 监控两个指标:流入流量和流出流量
      • 5-10、应用状态监控
        • 提供一种机制反馈自身的状态
        • 外部持续调用反馈接口,进行检查
        • 相关状态打印出来:数据库连接是否正常、缓存是否正常
      • 5-11、DNS监控
        • 实际服务产品,对域名都有依赖
        • dns故障并大面积影响并不少见,重视
        • 免费的DNS监控服务, 如DNSPod等
    • 报警实现
      • nodemailer模块 -> 邮件
      • 短信、电话报警
  • 6、稳定性
    • 多进程、
    • 多机器、 多机房
    • 容灾备份
    • 应用自身的部署考虑,如依赖的数据库、缓存等服务也要考虑。
  • 7、异构共存
    • 一部分是在全新的项目中应用,
    • 一部分是改造已有系统通过Node来提升性能。
    • 几乎没有将已有系统推翻用Node来进行重建的。