OS

    • TTY
    • [Doc] OS (操作系统)
    • [Doc] 命令行参数
    • [Basic] 负载
    • [Point] CheckList
    • [Basic] 指标

    你可以通过 w 命令查看当前登录的用户情况, 你会发现每登录了一个窗口就会有一个新的 tty.

    使用 ps 命令查看进程信息中也有 tty 的信息:

    1. $ ps -x
    2. PID TTY STAT TIME COMMAND
    3. 5530 ? S 0:00 sshd: dev@pts/3
    4. 5531 pts/3 Ss+ 0:00 -bash
    5. 11296 ? S 0:00 sshd: dev@pts/4
    6. 13318 pts/4 R+ 0:00 ps -x
    7. 23733 ? Ssl 2:53 PM2 v1.1.2: God Daemon

    其中为 ? 的是没有依赖 TTY 的进程, 即.

    在 Node.js 中你可以通过 stdio 的 isTTY 来判断当前进程是否处于 TTY (如终端) 的环境.

    1. $ node -p -e "Boolean(process.stdout.isTTY)"
    2. true
    3. $ node -p -e "Boolean(process.stdout.isTTY)" | cat
    4. false

    OS

    通过 OS 模块可以获取到当前系统一些基础信息的辅助函数.

    end of line (EOL) 同 newline, line ending, 以及 line break.

    通常由 line feed (LF, \n) 和 carriage return (CR, \r) 组成. 常见的情况:

    符号 系统
    LF 在 Unix 或 Unix 相容系统 (GNU/Linux, AIX, Xenix, Mac OS X, …)、BeOS、Amiga、RISC OS
    CR+LF MS-DOS、微软视窗操作系统 (Microsoft Windows)、大部分非 Unix 的系统
    CR Apple II 家族, Mac OS 至版本9

    如果不了解 EOL 跨系统的兼容情况, 那么在处理文件的行分割/行统计等情况时可能会被坑.

    • 信号常量 (Signal Constants), 如 SIGHUP, SIGKILL 等.
    • POSIX 错误常量 (POSIX Error Constants), 如 EACCES, EADDRINUSE 等.
    • Windows 错误常量 (Windows Specific Error Constants), 如 WSAEACCES, WSAEBADF 等.
    • libuv 常量 (libuv Constants), 仅 .

    Windows vs. POSIX

    看了上表之后, 你应该了解到当你处于某个平台之下的时候, 所使用的 path 模块的方法其实就是对应的平台的方法, 例如笔者这里用的是 mac, 所以:

    如果你处于其中某一个平台, 但是要处理另外一个平台的路径, 需要注意这个跨平台的问题.

    on POSIX:

    1. path.parse('/home/user/dir/file.txt')
    2. // Returns:
    3. // {
    4. // root : "/",
    5. // dir : "/home/user/dir",
    6. // base : "file.txt",
    7. // ext : ".txt",
    8. // name : "file"
    9. // }
    1. ┌─────────────────────┬────────────┐
    2. dir base
    3. ├──────┬ ├──────┬─────┤
    4. root name ext
    5. " / home/user/dir / file .txt "
    6. └──────┴──────────────┴──────┴─────┘

    on Windows:

    1. ┌─────────────────────┬────────────┐
    2. ├──────┬ ├──────┬─────┤
    3. root name ext
    4. └──────┴──────────────┴──────┴─────┘

    path.extname(path)

    case return
    path.extname(‘index.html’) '.html'
    path.extname(‘index.coffee.md’) '.md'
    path.extname(‘index.’) '.'
    path.extname(‘index’) ''
    path.extname(‘.index’) ''

    命令行参数

    命令行参数 (Command Line Options), 即对 CLI 使用上的一些文档. 关于 CLI 主要有 4 种使用方式:

    • node [options] [v8 options] [script.js | -e “script”] [arguments]
    • node debug [script.js | -e “script” | :] …
    • node —v8-options
    • 无参数直接启动 REPL 环境

    环境变量

    环境变量 简介
    NODE_DEBUG=module[,…] 指定要打印调试信息的核心模块列表
    NODE_PATH=path[:…] 指定搜索目录模块路径的前缀列表
    NODE_DISABLE_COLORS=1 关闭 REPL 的颜色显示
    NODE_ICU_DATA=file ICU (Intl object) 数据路径
    NODE_REPL_HISTORY=file 持久化存储REPL历史文件的路径
    NODE_TTY_UNSAFE_ASYNC=1 设置为1时, 将同步操作 stdio (如 console.log 变成同步)
    NODE_EXTRA_CA_CERTS=file 指定 CA (如 VeriSign) 的额外证书路径

    负载是衡量服务器运行状态的一个重要概念. 通过负载情况, 我们可以知道服务器目前状态是清闲, 良好, 繁忙还是即将 crash.

    通常我们要查看的负载是 CPU 负载, 详细一点的情况你可以通过阅读这篇博客: Understanding Linux CPU Load 来了解.

    命令行上可以通过 uptime, top 命令, Node.js 中可以通过 os.loadavg() 来获取当前系统的负载情况:

    1. load average: 0.09, 0.05, 0.01

    其中分别是最近 1 分钟, 5 分钟, 15 分钟内系统 CPU 的平均负载. 当 CPU 的一个核工作饱和的时候负载为 1, 有几核 CPU 那么饱和负载就是几.

    除了 CPU 负载, 对于服务端 (偏维护) 还需要了解网络负载, 磁盘负载等.

    CheckList

    有一个醉汉半夜在路灯下徘徊,路过的人奇怪地问他:“你在路灯下找什么?”醉汉回答:“我在找我的KEY”,路人更奇怪了:“找钥匙为什么在路灯下?”,醉汉说:“因为这里最亮!”。

    很多服务端的同学在说到检查服务器状态时只知道使用 top 命令, 其实情况就和上面的笑话一样, 因为对于他们而言 top 是最亮的那盏路灯.

    对于服务端程序员而言, 完整的服务器 checklist 首推 第二章中讲述的 USE 方法.

    The USE Method provides a strategy for performing a complete check of system health, identifying common bottlenecks and errors. For each system resource, metrics for utilization, saturation and errors are identified and checked. Any issues discovered are then investigated using further strategies.

    This is an example USE-based metric list for Linux operating systems (eg, Ubuntu, CentOS, Fedora). This is primarily intended for system administrators of the physical systems, who are using command line tools. Some of these metrics can be found in remote monitoring tools.











































    Software Resources




















    componenttypemetric
    Kernel mutexutilizationWith CONFIG_LOCK_STATS=y, /proc/lock_stat “holdtime-totat” / “acquisitions” (also see “holdtime-min”, “holdtime-max”) [8]; dynamic tracing of lock functions or instructions (maybe)
    Kernel mutexsaturationWith CONFIG_LOCK_STATS=y, /proc/lock_stat “waittime-total” / “contentions” (also see “waittime-min”, “waittime-max”); dynamic tracing of lock functions or instructions (maybe); spinning shows up with profiling (perf record -a -g -F 997 …, oprofile, dynamic tracing)
    Kernel mutexerrorsdynamic tracing (eg, recusive mutex enter); other errors can cause kernel lockup/panic, debug with kdump/crash
    User mutexutilizationvalgrind —tool=drd —exclusive-threshold=… (held time); dynamic tracing of lock to unlock function time
    User mutexsaturationvalgrind —tool=drd to infer contention from held time; dynamic tracing of synchronization functions for wait time; profiling (oprofile, PEL, …) user stacks for spins
    User mutexerrorsvalgrind —tool=drd various errors; dynamic tracing of pthread_mutex_lock() for EAGAIN, EINVAL, EPERM, EDEADLK, ENOMEM, EOWNERDEAD, …
    Task capacityutilizationtop/htop, “Tasks” (current); sysctl kernel.threads-max, /proc/sys/kernel/threads-max (max)
    Task capacitysaturationthreads blocking on memory allocation; at this point the page scanner should be running (sar -B “pgscan*”), else examine using dynamic tracing
    Task capacityerrors“can’t fork()” errors; user-level threads: pthread_create() failures with EAGAIN, EINVAL, …; kernel: dynamic tracing of kernel_thread() ENOMEM
    File descriptorsutilizationsystem-wide: sar -v, “file-nr” vs /proc/sys/fs/file-max; dstat —fs, “files”; or just /proc/sys/fs/file-nr; per-process: ls /proc/PID/fd | wc -l vs ulimit -n
    File descriptorssaturationdoes this make sense? I don’t think there is any queueing or blocking, other than on memory allocation.
    File descriptorserrorsstrace errno == EMFILE on syscalls returning fds (eg, open(), accept(), …).

    ulimit

    ulimit 用于管理用户对系统资源的访问.

    例如:

    1. $ ulimit -a
    2. core file size (blocks, -c) 0
    3. data seg size (kbytes, -d) unlimited
    4. scheduling priority (-e) 0
    5. file size (blocks, -f) unlimited
    6. pending signals (-i) 127988
    7. max locked memory (kbytes, -l) 64
    8. max memory size (kbytes, -m) unlimited
    9. open files (-n) 655360
    10. pipe size (512 bytes, -p) 8
    11. POSIX message queues (bytes, -q) 819200
    12. real-time priority (-r) 0
    13. stack size (kbytes, -s) 8192
    14. cpu time (seconds, -t) unlimited
    15. max user processes (-u) 4096
    16. virtual memory (kbytes, -v) unlimited

    注意, open socket 等资源拿到的也是 fd, 所以 ulimit -n 比较小除了文件打不开, 还可能建立不了 socket 链接.