@tars/node-agent

    它主要提供了如下的功能:

    • 内置负载均衡(通过 Cluster 模块实现)
    • 异常退出的监控与拉起
    • 日志搜集与处理
    • 支持TARS平台的管理命令
    • 支持 HTTP(s) 服务监控上报(在 TARS 平台上运行)
    • 支持服务用量上报(在 TARS 平台上运行)

    npm install @tars/node-agent -g

    用法

    node-agent app.js [options]

    • app.js 为程序的入口脚本,详见 节
    • [options] 可选配置,详见 选项

    例子

    执行 app.js 文件:

    $ node-agent app.js

    TARS 服务的配置文件来启动:

    $ node-agent app.js —config MTT.Test.conf

    启动并命名应用为 MTT.Test:

    $ node-agent app.js —name MTT.Test

    定义日志输出路径

    $ node-agent app.js —log ./logs/

    传递子进程 node 的启动参数:

    定义子进程数量:

    $ node-agent app.js -i 4

    入口点

    node-agent 启动时传入的第二个参数用来指定服务脚本执行的入口点文件,其中:

    • 可以直接传入脚本文件用于执行,如 ./app.js
    • 也可以传入脚本文件所在的目录,如 ./

    当传入的为目录时,入口点根据如下顺序进行确认:

    1. 目录中存在 package.json 文件,则:
      1. 查找 nodeAgent.main
      2. 查找 script.start(此配置节需要以 node 打头才可识别)
      3. 查找 main
    2. 查找目录中是否存在: server.jsapp.jsstart.jsindex.js

    只要其中的一项匹配则作为入口点文件来执行,并不再往下匹配。

    Options:

    -h, —help output usage information-V, —version output the version number-c, —config specify tars config file. NOTE: independent config will be override this-n, —name set a for script - e.g. app.servername-l, —log specify log file-i, —instances launch [number] instances (for networked app)(load balanced)—env <environment_name> specify environment to get specific env variables (for JSON declaration)—http-address <http_address> specify http ip:port address to pass to script - e.g. 127.0.0.1:80—script-args <script_args> space delimited arguments to pass to script - e.g. —use=”https”—node-args <node_args> space delimited arguments to pass to node - e.g. —node-args=”—debug=7001 —trace-deprecation”—run-as-user <run_as_user> The user or uid to run a managed process as—run-as-group <run_as_group> The group or gid to run a managed process as—max-memory-restart specify max memory amount used to autorestart (in megaoctets)—graceful-shutdown specify graceful shutdown timeout (in millisecond), default is 8000ms—exception-max <exp_max> The program will be terminated if an exceeding max exception count, default is 5—exception-time <exp_time> The program will be terminated if an exception occurs within a particular period of time, default is 5000ms—keepalive-time <detect_time> specify the interval for detecting the worker which could be set to [off] if you want to debug and the default value is 60s—applog-max-files <applog_max_files> specify max number of rolling log, default is 10—applog-max-size <applog_max_size> specify max file size for each rolling log, use human readable unit in [K|G|M], default is 10M—applog-level <applog_level> define log level, default is DEBUG—tars-node <tars_node> set tars node conncetion string, agent would send notifications to tars node - e.g. tars.tarsnode.ServerObj@tcp -h 127.0.0.1 -p 10000 -t 60000—tars-local <tars_local> set local interface setup string, agent would receive the notifications from tars node - e.g. tcp -h 127.0.0.1 -p 10000 -t 3000—tars-monitor <tars_monitor> enable or disable service monitor running in tars platform, and the default value is on—tars-monitor-http-threshold <http_threshold> if the http(s) status code is large than the preseted threshold then this request will be considered error. default threshold is 400, set it “off” to disabled—tars-monitor-http-seppath <http_seppath> separate url pathname as interface name, default is on

    -c, —config

    如果此服务为 TARS 服务,可在此指定服务的配置文件。

    配置文件将会自动读入作为基础配置,通过设置其他的配置参数可覆盖读入的基础配置。

    -n, —name

    可在此指定服务名。

    • 如未配置,则使用 脚本的文件名
    • 如为 TARS 服务,则服务名必须为 app.serverName 格式

    -l, —log

    指定输出的日志文件根目录

    如未配置,则所有日志输出采用 stdout/stderr 输出

    -i, —instances

    node-agent 采用 Node.js 原生的 模块来实现负载均衡。

    可在此配置 node-agent 启动的子进程(业务进程)数量:

    • 未配置(或配置为 auto0),启动的子进程数量等于 CPU 物理核心 个数。
    • 配置为 max,启动的子进程数量等于 CPU 个数(所有核心数)。

    如果 node-agent 是由 tarsnode 启动的,会自动读取TARS配置文件中的 tars.application.client.asyncthread 配置节。

    也可通过 TARS平台 -> 编辑服务 -> 异步线程数 进行调整。

    —env

    设置服务启动时的 环境变量 , 这里需要使用 JSON 格式进行描述

    例如:可以通过这个配置来传入当前的运行环境(开发、生产)

    请注意:当作为命令行参数传递时,这里的双引号(”)需要进行转义(”)

    如果此服务为 TARS 服务,则此参数以 tarsnode 可识别的方式读取并设置。

    —http-address

    设定服务脚本执行所需的 ip:port

    在脚本中可以使用环境变量 HTTP_IPIP)、HTTP_PORTPORT) 进行获取

    如果此服务为 TARS 服务,则这里的值为配置文件中,第一个非TARS协议的 Servant 指明的 ip:port

    —script-args

    设置服务脚本执行所需传入的参数

    例如:

    等同于

    $ node app.js —use=”https”

    —node-args

    设置 node cluster 子进程所需的启动参数

    例如:

    等同于

    $ node —debug=7001 —trace-deprecation app.js

    —run-as-user, —run-as-group

    指定 node cluster 子进程运行的用户(组)

    可通过此对服务脚本进行降权执行,如未配置权限等同于 node-agent 启动用户(组)

    —max-memory-restart

    指定服务所能使用到的最大内存。

    如果子进程达到最大内存限制,将会抛出异常并退出。此 (资源形) 异常 也会纳入整体的异常进行处理。

    —graceful-shutdown

    正常情况下,node-agent 在停止服务(进程)时会通过 worker.disconnect() 通知服务,让服务释放资源并退出。

    在这里可以设置超时时间,如果服务(进程)在给定的时间后仍然没有退出,node-agent 则会强制 kill 掉进程。

    超时时间默认为 8 秒

    如果 node-agent 是由 启动的,会自动读取TARS配置文件中的 tars.application.server.deactivating-timeout 配置节。

    —exception-max, —exception-time

    如果(服务)子进程出现异常退出,并在一段时间内 (—exception-time) 异常退出的次数没有超过最大值 (—exception-max)node-agent 将会自动拉起新的(服务)子进程,否则 node-agent 与服务也将异常退出。

    以方便第三方管理工具对服务状态进行监控

    —exception-time 默认值为 10s—exception-max 默认值为 2次

    —keepalive-time

    如果 node-agent 在一段时间(—keepalive-time)内未收到(服务)子进程发送的心跳,则判定此(服务)子进程为僵尸进程(zombie process),将会直接杀死 kill,并作为异常进行处理。

    当服务器 可用内存 过小时不触发此逻辑。

    如果您想对服务脚本进行(断点)调试,这需将此设置成为 --keepalive-time=off

    其默认值为 5m

    —applog-max-files, —applog-max-size, —applog-level

    指定服务默认的滚动 日志大小 (—applog-max-size) 、 总数 (—applog-max-files) 与 日志级别 (—applog-level)

    服务的启动时会创建两份主(滚动)日志:

    • app.serverName.log: 所启动服务的 stdout/stderr/console
    • app.serverName_agent.log: node-agent 的状态信息

    这个配置主要影响上面两份主(滚动)日志的输出参数

    详见 日志

    —tars-node, —tars-local

    如果 node-agent 是由 tarsnode 启动的,则需要指定 tarsnode 的 RPC 连接参数 (—tars-node) 与本地被调的启动参数 (—tars-local)

    此设置也可通过 TARS配置文件 (—tars-config) 进行指定。

    node-agent 会在服务启动时向 tarsnode 上报服务的版本,并在服务运行过程中发送心跳包。

    与此同时,node-agent 本地启动的(被调)服务也将从 tarsnode 中接收下发的消息(shutdown/message),并进行响应。

    —tars-monitor

    如果您的服务是在 TARS 平台上运行的,node-agent 会自动向 tarsstat 上报服务的监控(用量)信息。

    默认值为 on,设置为 off 可关闭自动上报功能。

    具体详情可查看 监控与用量上报 节。

    —tars-monitor-http-threshold

    如果您的服务的 HTTP(s) 返回码大于此阈值则此次请求将作为异常访问进行上报。

    默认 response.statusCode >= 400 则为异常访问。

    设置为 off 可关闭此特性。

    具体详情可查看 监控与用量上报 节。

    —tars-monitor-http-seppath

    HTTP(s) 服务在上报时是否需要区分不同路径。

    默认为区分路径,其中 url.pathname 的部分会作为服务的接口名进行上报。

    具体详情可查看 监控与用量上报 节。

    配置

    node-agent 支持以多种配置方式进行启动:

    • 命令行参数进行指定
    • 在服务脚本的 package.json 中指定

    其中:

    • package.jsonTARS 配置文件中指定的值,会覆盖掉命令行参数中所指定的配置项。
    • 可以通过驼峰式写法将配置参数声明在 package.jsonnodeAgent 的配置节。
    • TARS 服务的配置文件中以配置参数原型直接进行声明

    例如(以 nobody 用户启动子进程):

    命令行参数:

    node-agent app.js —run-as-user=nobody

    package.json:

    TARS 配置文件:

    消息与事件

    一般情况下,用户代码无需处理(关注)进程消息与事件,但如果您想处理(响应):进程退出、TARS管理命令,则需要进行处理。

    process.on(‘disconnect’, function)

    关于此事件具体说明请参考

    默认情况下 node-agent 会对该事件进行处理,但如果用户代码监听(处理)了该事件则 node-agent 将不再进行处理。

    请注意:您在处理完该事件后,请一定显示调用 process.exit() 以确保进程可以正常退出

    process.on(‘message’, object)

    一旦 node-agent 收到了来自于 tarsnode 的管理命令,将会通过进程消息发送给业务脚本。

    传递的消息 object 的格式为:

    支持的消息 cmd 有:

    • tars.viewstatus : 查看服务状态
    • tars.setloglevel : 设置日志等级
    • tars.loadconfig : PUSH配置文件
    • tars.connection : 查看当前链接情况
    • 自定义命令

    存在有 datacmd 有:

    • tars.setloglevel : INFODEBUGWARNERROR
    • tars.loadconfig : 配置文件名
    • 自定义命令

    * node-agent 会对 自定义命令 进行切分,命令中第一个空格前的字符作为 cmd,而后续的部分则作为 data

    日志

    node-agent 会将服务的输出(stdout|stderr 管道以及 console 模块的输出)重定向到指定的文件(当使用 -l --log 参数启动时)或者管道。

    日志的输出由 winston-tars 模块实现,其输出的日志格式为:日期 时间|PID|日志级别|文件名:行号|内容

    服务脚本可以通过 node 自带的 console 模块输出不同级别的日志。

    也可通过服务的 stdout|stderr 管道输出。

    process.stdout = INFOprocess.stderr = ERROR

    日志级别的优先级为: INFO < DEBUG < WARN < ERROR < NONE

    其中,默认的日志级别为:DEBUG

    node-agent 通过环境变量向服务脚本提供所需的变量:

    • process.env.IP:HTTP(s) 可监听的 IP。
    • process.env.PORT:HTTP(s) 可监听的端口。
    • process.env.WORKER_ID 进程顺序 ID(例如启动 8 个进程,第一个为0,第二个为1,以此类推),重新启动的进程仍然使用之前的 ID。

    如服务是由 tarsnode 启动的,还支持如下变量:

    • process.env.TARS_CONFIG:启动服务所使用的TARS配置文件所在的绝对路径。
    • process.env.TARS_MONITOR:是否开启监控(特性)上报(统计)。

    请注意:环境变量全为 String 类型

    监控与用量上报

    如果您的服务是在 TARS 平台上运行的,node-agent 会自动向 tarsstat 上报服务的监控(用量)信息。

    监控信息

    监控信息的上报与您启动的服务及其调用者有关(可通过 TARS平台 -> 服务监控 查看):

    更多详情您可访问 @tars/monitor.stat 获取。

    用量信息

    无论您启动的服务是什么类型,用量信息总是上报(可通过 TARS平台 -> 特性监控 查看):

    • memoryUsage: 内存用量,将会上报 rssheapUsedheapTotal 这三个用量(单位为字节)
    • cpuUsage: CPU用量,将会上报CPU使用率,数据汇总为逻辑单核(单位为百分比)
    • eventloopLag: 事件循环滞后(V8消息队列延迟),每隔2秒采样(单位为毫秒)
    • libuv: I/O用量,将会上报 activeHandlesactiveRequests 这两个用量

    所有的用量信息的统计策略均为 AvgMaxMin

    无损操作

    如果您的服务是在 TARS 平台上运行的,每次无损重启或发布时:

    1. 设置流量状态为无流量(包括路由和第三方流量)
    2. 等待调用方获取配置(默认为 2分13秒)
    3. 执行对应操作(重启或发布)
    4. 恢复流量状态

    请注意:如果大量节点同时进行无损操作,会同时屏蔽这些节点的流量,可能会造成服务不稳定。建议采用无损分批重启。

    预热

    在无损操作的服务启动过程中,可以选择是否需要进行预热:

    1. 服务启动后每秒检查是否所有子进程都监听了端口(所有子进程状态均为 ONLINE)
    2. 如果超过预热超时时间,且并非所有子进程都监听了端口,则无损操作流程失败并通知用户(邮件通知)

    我们强烈建议您:在任何情况下,请完成所有初始化操作后再监听(listen)端口。

    架构

    node-agent 在启动(也就是执行 cluster.fork)服务脚本时,并不会直接载入对应脚本,而是载入 node-agent/ProcessContainer.js 来对服务脚本进行包装,之后再调用系统的 require 载入执行脚本