NodeServer技术运维调研与探索

为何要用公司内部的框架, 直接跑服务不好么?

简单的部署运维 pm2 + (koa or express) + MongoDB
可能遇到的问题:

  • 日志怎么管理?
  • 有没有服务监控与告警?
  • 怎么快速部署, 扩容?
  • 运维管理还得用命令行?
  • 负载均衡咋办?

结论: 尽可能接入公司现有的运维与技术框架, 减少开发成本与运维成本,提高系统的稳定性和安全性

tips: 虽然目前 pm2 等工具已经非常强大, 也提供现有的运维监控平台,但是由于服务运维是关键的路径,直接使用第三方还是需要详细研究, 目前还是使用自研的产品比较好

公司现有的管理运维平台

Node in tars – Node.js 大规模商用平台

TSW – 针对web前端开发同学的server端web开发解决方案 https://tswjs.org/

Node in tars :

  1. 无需进行任何代码层面的的变更
  2. 在线的进程管理系统与运维平台
  3. 实时的日志查询
  4. 系统用量与请求监控
  5. 快速部署工具

###SNG-TSW

  1. 开箱自带内部通用组件接口特性
  2. TSW 作者维护 tsw 包的版本, 机器负责人负责机器包更新
  3. 实时日志系统与服务端抓包
  4. 与包发布发布系统耦合
  5. 开源框架的兼容
  6. 路由,全局变量,常用 util

一个技术框架与运维体系的应有的功能与组成

  • 进程管理
  • 请求监控 与 用量监控
  • 日志与监控告警平台
  • debug 定位问题
  • 接入公司内部标准组件
  • 开发流程
  • 部署流程
  • 启动,停止,重启,热重启
  • 扩容与迁移

进程管理

TSW:

  • 主进程负责监听端口,分发请求
  • worker进程负责处理业务
  • 负载均衡

TSW

Node in tars:

tars

tips: 由主进程负责监听端口,接收新连接后再将连接循环分发给工作进程
有一种基于round-robin 算法的模型,master 进程创建socket, 绑定地址端口, 同时负责监听
当获取到新的连接之后(调用 accept 方法与客户端建立 tcp 连接), 再将这个连接分发到指定的 worker 进程, 这里如何分发到指定的 worker 进程是可控的, 这里使用了 round-robin 算法, 当然还有其他的算法也可以用于请求的分发.

请求监控用量监控

  • tars:
    • 系统集成自带的监控
    • SET 内存、CPU用量数据,以及 eventloop 滞后数据
  • TSW: 主要依赖于公司平台级别的监控

    1. 机器性能监控
    2. kv 运行查看
    3. 模块调用日志
    4. 流水

    tips: eventloop 滞后的定义

作者给出的定义: js主线程处理不过来了,计算方法为: setTimeout 2s,然后减去2s, 得到的非0值就是滞后时间

我的理解: EventLoop 滞后根据 js 的 event 事件模型中的概念来看的话: 可以作为一个指标来衡量 event 事件队列的长度, 比如

1
2
3
4
5
function a(){
setTimeout(function(){alert('1');}, 0);
alert('2');
}
a();

这里 alert(1), 会滞后 alert(2) 执行, 这个之间的时间差可以用来作为 eventloop 滞后数据指标
(这是我分析了event 事件的运行机制得出, 可能不一定准确, 有错误希望指出)

日志

TSW:

  • 实时日志
  • 历史日志
  • 服务器本地日志

Node in tars:

  • Console 重定向到特定的日志
  • 管理端动态变更日志基本
  • 实时日志查看客户端

监控告警平台

TSW:

  • 邮件告警, 自主配置通知者(业务模块、请求头、错误堆栈等)
  • 模调低于阈值98%告警(短信、内部IM信息通知)

tars:

  • 系统/网络层监控(系统负载,磁盘,网络连通性)
  • 应用层监控(ps,http,log,port)
  • 业务层监控: pp监控(自定义多维度上报)

debug 定位问题

TSW:

  • 服务端抓包 (毫秒级延时)
  • log(14天)
  • 服务器端日志
  • 染色

tars

  • 实时日志查看
  • 管理平台更改日志输出级别
  • 染色 平台

开发流程与部署流程

TSW:

  • 推荐本地搭建 tsw 环境调试
  • 需要应用接入 tsw(成本较低)
  • 支持 文件 提单发布
  • 包发布打包发布(推荐)

tars

  • 无需配置环境, tars 只是一个运行容器, 本地开发调试
  • nodetools 发布工具
  • Svn, git 在线编译与发布

tips: 在 tars 中,正式部署分为:编译与发布两个环节。
编译环节中,先在平台上配置 SVN / GIT 并打 TAG 之后即可编译。
编译完成了之后即可选择不同的版本进行发布,一旦发布出现问题则可快速进行回滚操作。

启动,停止,重启,热重启

  • 包发布包中设置重启脚本
  • 安装或升级完成之后直接点击热重启或者重启
  • tars也支持在管理页面重启应用等操作
  • reload方案: 60秒刷新cache , 对性能损耗3%

扩容

  • TSW: 包发布自动化一键安装(安装包,下发配置)

—————-分割线—————

一点小改变: 在docker容器中运行NodeServer

核心概念

  • Docker 镜像(Image)就是一个只读的模板。
  • 仓库(Repository)是集中存放镜像文件的场所,
  • 容器(Container)是从镜像创建的运行实例。它可以被启动、开始、停止、删除

tips: Docker 和传统虚拟化方式的不同之处, Docker 的基础是 Linux 容器(LXC),容器是在操作系统层面上实现虚拟化,直接复用本地主机的操作系统,而传统方式则是在硬件层面实现。

镜像 ufs 容器

Dockerfile是由一系列命令和参数构成的脚本,这些命令应用于基础镜像并最终创建一个新的镜像。
镜像ufs容器

1
2
3
4
5
// Dockerfile
FROM ubuntu:14.04
ADD run.sh /
VOLUME /data
CMD ["./run.sh"]

FROM ubuntu:14.04 :设置基础镜像,此时会使用基础镜像 ubuntu:14.04的所有镜像层,为简单起见,图中将其作为一个整体展示。
ADD run.sh /:将Dockerfile所在目录的文件run.sh加至镜像的根目录,此时新一层的镜像只有一项内容,即根目录下的run.sh.

VOLUME /data:设定镜像的VOLUME,此VOLUME在容器内部的路径为/data。需要注意的是,此时并未在新一层的镜像中添加任何文件,但更新了镜像的json文件,以便通过此镜像启动容器时获取这方面的信息。

CMD [“./run.sh”]:设置镜像的默认执行入口,此命令同样不会在新建镜像中添加任何文件,仅仅在上一层镜像json文件的基础上更新新建镜像的json文件。

初始层(Init Layer)与可读写层(Read-Write Layer),初始层中大多是初始化容器环境时,与容器相关的环境信息,如容器主机名,主机host信息以及域名服务文件等。

构建基础镜像与开发部署流程

使用流程

  1. 开发代码
  2. 将代码打入现有的基础镜像
  3. build 出来 release 镜像
  4. 创建容器运行服务

容器管理与运维

docker 三剑客

优势

  • 告别紊乱的开发环境
  • 开发-生产环境,为应用提供了一致的环境
  • 应用程序运行环境隔离
  • 自带版本控制功能
  • 提升研发交付和运维上线效率
  • 快速部署

回顾

从部署一个app.js开始, 多维对比 tsw 和tars, 设想Node服务与容器结合, 其实太多的技术细节我们都不了解了, 还是要一步一步慢慢来, 先做好基础技术储备, 一步一个脚印, 从现在的1.0 技术储备时代转向 2.0小规模业务使用的探索时代