首页 / 资讯中心 / 文章详情

进程、资源观察与 Systemd 服务管理

进程、资源观察与 Systemd 服务管理 ★ FEATURED ARTICLE
一、程序、进程、线程一句话分清程序是磁盘上的可执行文件比如 /usr/sbin/nginx它安安静静躺在硬盘上还没有运行关键标识是文件路径。进程是程序的一次运行实例。程序一旦被启动操作系统就给它一份独立的内存、文件描述符和运行身份并发给一个编号这个编号就是 PID。线程是进程内部的执行单元。一个进程内部可以开很多线程它们共享进程的内存和资源每个线程有自己的编号 TID也叫 LWP。同一个程序可以同时运行成多个进程。Nginx 就是这样磁盘上只有一份 /usr/sbin/nginx启动后却形成一个 master process 和多个 worker process它们是不同的进程各有各的 PID。千万不要把 worker 误认为线程而 Jenkins 那种 Java 程序反过来通常只有一个 Java 主进程内部跑着很多线程。二、PID、PPID 与进程树PID 是进程编号系统里每个进程都有且同一时刻不重复。PPID 是父进程编号记录这个进程是由谁启动的。Linux 里所有进程的祖先都是 systemd它的 PID 固定是 1。Nginx 由 systemd 拉起master 的 PPID 指向 1worker 由 master 拉起worker 的 PPID 指向 master。顺着 PPID 一路往上追就能画出一棵进程树。排查问题时这棵树能告诉你一个进程到底是谁启动的、归谁管。三、进程状态R、S、D、T、Z40 个玩家是 40 个进程2 个服务器核心是 2 个 CPU 核心。正在游戏里的是 Running匹配成功、排队进图的是 Runnable。这两类在ps里都显示为 R。等硬盘加载地图的是 D 状态等待不可中断 I/O不响应普通信号kill也杀不掉。等队友上线的是 S 状态可中断睡眠队友一上线就唤醒。还有 T 和 Z被裁判暂停的是 T角色已退出但队伍仍占位、队长没确认的是 Z僵尸子进程结束但父进程没读取退出状态。核心映射都一样Running/Runnable → R可中断睡眠 → S不可中断 I/O → D暂停 → T僵尸 → Z。四、观察进程的几类工具ps 是拍照拍一张当前所有进程的快照。ps aux 看用户、CPU、内存和完整命令行ps -ef 看 PID、PPID 和父子关系ps -eo 可以自己挑字段。pgrep 和 pidof 是查号台直接按名字返回 PID省去自己 grep。pgrep -o 取最早启动的那个Nginx 场景下通常就是 master。pstree 是画家把进程树画出来-p 带 PID-s 沿父进程向上追。top 和 pidstat 是录像连续刷新观察。ps 只拍一张异常往往是趋势要看连续画面才能下结论。ss 是查端口登记簿ss -lntp 能从端口号反查出是哪个进程在监听顺着端口找到 PID再找到程序和 Unit。五、信号礼貌敲门与强行破门信号是请求或强迫进程做动作的方式。Day 09 重点讲三个TERM15 号礼貌敲门请求进程正常退出。进程有机会保存数据、关闭文件、通知伙伴。优先使用。HUP1 号具体行为由程序定义很多服务把它当作重新加载配置的指令。用之前先查文档。KILL9 号强行破门。它由内核直接执行进程根本没有机会清理现场可能留下锁文件、丢数据。是最后手段。正确顺序永远是先确认 PID再发 TERM等一等、验证一下实在退不出去才用 KILL。管理 Systemd 服务时更优先用 systemctl stop 或 reload让超时和子进程都由 Systemd 统一处理。六、前台、后台与 nohup前台运行命令占着当前终端终端不能干别的。命令后面加 直接放到后台跑终端腾出来了$! 保存它的 PID。CtrlZ把前台正在跑的命令暂停变成 Stopped 状态。bg %1让 1 号作业在后台继续跑fg %1 把它带回前台jobs -l 随时看作业列表。注意 %1 是作业编号只在当前 Shell 有效不是 PID。nohup让命令在终端关闭后继续运行输出写进文件。适合临时任务长期服务应该交给 Systemd因为 Systemd 还提供开机自启、失败恢复、统一日志和运行身份管理。七、Load Average系统的排队长度uptime 显示最近 1、5、15 分钟的 Load Average可以理解为任务排队长度。判断时要除以 CPU 核心数nproc 告诉你有几个核心。以 4 核、负载 8.00、4.00、2.00 为例1 分钟值除以 4 是 2.0每个核心平均排 2 个任务压力较高5 分钟值是 1.0接近满载15 分钟值是 0.5有余量。三个值从过去到现在是 0.5、1.0、2.0说明压力正在爬升。两个关键认知每核心负载小于 1 通常有余量接近 1 是满载大于 1 说明有任务在排队或 D 状态任务多。Load Average 统计了 D 状态任务所以它不等同于 CPU 使用率。磁盘卡住也会抬高负载。第一轮用它快速判断最终要结合 top、vmstat 和业务表现确认。八、内存available 才是真话free -h 里最容易看错的是这一条内存看起来很忙不等于内存不够。Linux 会把暂时空闲的内存拿去做缓存cache 保存近期读过的文件数据下次读同一个文件就不用碰磁盘buffer 暂存并整理准备写入磁盘的数据。这些缓存随时可以回收回收后给应用程序用。所以看内存要优先看 available 这一列它才是真正可用的量buff/cache 很高不是坏事。Swap 是拿磁盘当内存的应急通道。si、so 这些换入换出动作说明物理内存真的紧张了。Swap 只能临时缓解不能代替物理内存。九、vmstat 与 /procvmstat 1 5 每 1 秒采样一次共 5 次。r 是等 CPU 的任务数si 和 so 是 Swap 换入换出us、sy、id 是用户态、内核态、空闲 CPU 占比wa 是等 I/O 浪费的 CPU 时间。第一行是开机以来的平均值判断趋势要看后面的行。/proc 是内核提供的运行状态入口不是普通目录。/proc/PID/status 看进程状态、内存、线程数/proc/PID/cmdline 看启动参数/proc/PID/fd 看打开的文件。PID 消失对应目录也跟着消失。/sys 是设备与内核属性视图比如 /sys/class/net 看网卡、/sys/class/block 看块设备。本阶段只读不改错误修改可能影响系统运行。十、Systemd 与 Unit服务的总管家Systemd 是 Ubuntu 的系统与服务管理器PID 为 1开机后第一个启动。所有长期服务的启动、停止、重启、开机自启、崩溃后拉起都归它管。Unit 是一份声明式的说明文件告诉 Systemd这个服务怎么启动、以谁的身份跑、挂了要不要重启、要不要开机自启。常见类型.service 长期服务、.socket 套接字监听、.timer 定时触发、.target 组合目标、.mount 挂载点。systemctl 是操作这些 Unit 的统一入口。三个容易混淆的命令daemon-reload改了 Unit 文件本身让 Systemd 重新读一遍定义。它不会重启任何服务。reload服务的配置文件改了让服务进程自己重新加载配置进程不换、PID 不变前提是程序支持这个动作。restart整个进程停掉再拉起PID 通常改变。十一、四层检查判断服务真的活着一个服务显示 active只说明 Systemd 认为它起来了。完整的健康确认要过四层Unit 层systemctl is-active 或 status确认服务状态正常。进程层pgrep 或 ps确认进程真的存在、身份对。端口层ss -lntp确认该监听的端口在监听。应用层curl 一个真实 URL确认程序能返回正确响应。这个顺序从里到外一层层排除。后面排查故障也按这个顺序复测。十二、Nginx 多进程与 Jenkins 多线程两种服务模型对比Nginx一个 master 加多个 worker多个 PID监听 80 端口软件包安装时自带 Unit。观察重点是多个进程各自的 CPU、内存。Jenkins WAR一个 Java 主进程内部很多线程一个 PID 多个 TID监听 8080 端口Unit 需要自己写。观察重点是用 ps -L 或 top -H 深入到线程层面。不管哪种模型最后都交给 Systemd 管理这是本课的主线先看懂进程再学会控制进程最后把程序交给 Systemd。十三、Service Unit 的四个核心问题写一个最小可用的 Service Unit先回答四个问题按什么顺序启动Afternetwork.target 表示网络就绪后再启动。以谁的身份运行User 和 Group 指定专用账号不用 root。执行哪个程序ExecStart 写清楚启动命令和参数。失败后怎样处理Restarton-failure 表示异常退出时自动拉起RestartSec5 表示等 5 秒再拉。先写最小可用 Unit再按需要补充资源限制等内容。另外 SuccessExitStatus143 的作用是143 等于 128 加 15是进程收到 TERM 信号的退出码把它声明为正常退出可以避免正常 stop 被当成失败而触发重启。十四、nice 值CPU 调度的谦让度Nice 值范围 -20 到 19数值越小越优先越大越谦让。普通用户可以调低自己进程的优先级变得更好说话但调高优先级需要管理员权限。要注意 Nice 只影响 CPU 调度的倾向不保证执行先后也不限制用量不能拿来解决磁盘、网络或锁等待问题。十五、僵尸进程为什么杀不掉僵尸进程本身已经结束了只剩一条退出状态记录等父进程来读。它不占 CPU 也几乎不占内存但对它发 kill -9 没有任何用因为它已经死了。正确的思路是去调查它的父进程为什么迟迟不回收必要时让父进程处理问题或重启父进程。
阅读完成 · 觉得有帮助?
咨询建站