Skip to content

Linux 系统

程序

程序,program;文件系统中以普通文件存在(通常为 binary program)。

进程

进程,process;程序触发后,用户权限与属性、二进制代码与所需资料会被载入内存单元中,操作系统会分配识别码(PID, Process ID)给这个单元。

父进程(PPID, Parent Process ID)

程序有依附性!一般程序依赖于 shell 环境执行其结构如同树状。

sh
$ pstree -l
systemd─┬─agetty
        ├─auditd───{auditd}
        ├─chronyd───chronyd
        ├─cron
        ├─dbus-daemon
        ├─polkitd───2*[{polkitd}]
        ├─rsyslogd───3*[{rsyslogd}]
        ├─smartd
        ├─sshd───sshd───sshd───bash───pstree
        ├─systemd───(sd-pam)
        ├─systemd-journal
        └─systemd-logind

执行顺序

PRI, priority 执行优先值,一个 CPU 周期内 PRI 值越低可能优先以及较多次执行该程序。

PRI 是弹性规划的不能直接修改,NI 值可变动,并于下一周期影响到 PRI。

PRI(new) = PRI(old) + NI

NI 自定义

  • root 可调节范围:-20 ~ 19
  • 普通用户 可调节范围:0 ~ 19 (防止抢占系统资源)
sh
# alter priority of running processes
$ renice
$ renice -n <n> -p <pid>

进程管理

程序读取写入内存中成为一个进程单位。通过给予进程一个信号(signal)决定进程行为。

下列是部分信号代码:更多见 man 7 signal

代码名称行为
1SIGHUP启动被终止的程序,让 pid 重新读取配置,类似重新启动。
2SIGINTinterrupt,中断一个进程,相当于 [ctrl] + [c]
9SIGKILL强制中断
15SIGTERMterminate,正常终止程序。
19SIGSTOPSTOP,暂停程序,相当于[ctrl] + [z]
sh
# send a signal to a process
$ kill
# 默认给予 signal 值 15 意为正常关闭程序
$ kill <SIG> <PID>

# kill procewses by name
$ killall
$ kill <SIG> <name>

退出状态码

sh
$ echo $?
# 0: 正常结束
# 127: command not found

查询

用户相关

sh
$ ps -l
F   UID     PID    PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND
0  1000  152654  152653  20   0   9868  6156 do_wai Ss   pts/0      0:00 -bash
0  1000  158577  152654  20   0  11084  4492 -      R+   pts/0      0:00 ps l
  • F(flag): 进程标志
    • 0:一般用户进程
    • 1:复制(forked)但未执行进程
    • 4:root 用户进程
  • S(stat): 进程状态
    • R(running/runnable/run queue):正在执行、可执行、队列中的进程
    • S(interruptible sleep):可被唤醒的休眠状态。
    • D(uninterruptiable sleep):不可被唤醒的休眠状态。
    • T(stop by job control):工作控制,后景暂停状态。
    • t(stop by debugger):debugger 出错
    • Z(Zombie):僵死状态,程序已终止却无法从内存移除。
  • UID:User ID
  • PID:Process ID
  • PPID:Parent Process ID
  • C:CPU 使用率,单位百分比。
  • PRI(priority): 数值越小,优先执行。
  • NI(nice):与 PRI 相关,可被修改。
  • ADDR:内存相关,kernal function,内存地址(TODO),Running 状态一般显示为 -
  • SZ:内存相关,占用内存大小。
  • WCHAN:内存相关,是否运行状态,运行时一般显示 -
  • TTY:终端位置,远程登录则使用动态终端 pts/n
  • TIME:进程使用 CPU 时间
  • CMD:command

所有进程

sh
# a, show command line arguments
# u, show uid transitions
$ ps -aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.0  0.5 202196 45528 ?        Ss   Jan01   0:03 /sbin/init
root           2  0.0  0.0      0     0 ?        S    Jan01   0:00 [kthreadd]
root           3  0.0  0.0      0     0 ?        I<   Jan01   0:00 [rcu_gp]
root           4  0.0  0.0      0     0 ?        I<   Jan01   0:00 [rcu_par_gp]
root           5  0.0  0.0      0     0 ?        I<   Jan01   0:00 [slub_flushwq]
root           6  0.0  0.0      0     0 ?        I<   Jan01   0:00 [netns]
  • USER
  • PID
  • %CPU
  • %MEM
  • VSZ:process 占用的虚拟内存量(Kbytes)
  • RSS:process 占用的固定内存量(Kbytes)
  • TTY
  • STAT:R/S/T/Z
  • START:触发的时间
  • TIME
  • COMMAND

树状分支

sh
# 进程树型
# A, use ASCII line drawing charaters
$ pstree -A
# u, show uid transtions
# p, show pids
$ pstree -Aup

实时

sh
# display Linux processes
$ top
top - 18:32:38 up 3 days, 19:40,  2 users,  load average: 0.00, 0.03, 0.06
Tasks: 140 total,   1 running, 139 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  1.4 sy,  0.0 ni, 98.4 id,  0.2 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :   7850.5 total,   5090.9 free,   1042.9 used,   2019.0 buff/cache
MiB Swap:   1953.0 total,   1953.0 free,      0.0 used.   6807.5 avail Mem
  • top - 18:32:38 up 3 days, 19:40:累计运行时间
  • load average:平均工作负载,5、10、15min,单位时间。CPU 需要运行几个任务。(例如,CPU 有8个核心,那么数据低于8是可以接受的。即,每个核心负责一个工作)
  • Tasks:进程数
  • running
  • sleeping
  • stopped
  • zombie
  • %CPU(s)
    • id(idle):系统闲置
    • wa:数值越高,表明系统的限制在磁盘或网络
  • Mem:内存总量
    • free:空闲
    • buff/cache:系统获取文档资料暂存,以加速未来存取文件效能。
  • Swap:交换分区
  • avail Mem:free + buff/cach
sh
# 续上
    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
 161907 root      20   0   11612   5036   3136 R   0.3   0.1   0:00.11 top
      1 root      20   0  202196  45528  17000 S   0.0   0.6   0:03.09 systemd

软件管理

epel, Extra for Package Enterprise Linux (RHEL)

sh
$ yum
$ rpm
$ apt
$ dpkg

定时任务

$ apt install at
# queue, examine, or delete jobs for later execution
$ at
# darmon to execute scheduled commands
$ cron

daemon

systemd, System Daemon;负责系统启动过程,管理系统守护进程、服务、挂载点、套接字。

  • systemd:主进程(PID 1),管理系统和服务生命周期。
  • systemctl:客端工具,管理 systemd
  • journalctlsystemd日志工具
  • systemd-analyze:系统性能分析工具
  • systemd-cgls:控制组(cgroup)层次结构

优先顺序

  1. system units created by the administrator:/etc/systemd/system
  2. runtime units:/run/systemd/system
  3. system units installed by the administrator:/usr/lib/systemd/system

单元类型

序号类型描述
1service服务单元,系统服务
2socket套接字单元,进程间通信套接字
3device设备单元,内核识别的设备
4mount挂载单元,文件系统挂载点
5automount自动挂载单元,按需自动挂载
6swap交换单元,交换分区/文件
7target目标单元,单元组
8path路径单元,文件系统路径变化触发
9timer定时器单元,定时任务
10slice切片单元,资源管理组
11scope范围单元,外部创建的进程

一些 target

  • rescue.target 单用户救援模式
  • emergency.target 紧急模式
  • multi-user.target 多用户终端模式
  • getty.target tty, TeleTYpewriter 创建
  • graphical.target 图形终端模式
sh
$ systemctl status <unit>
$ systemctl start <unit>
$ systemctl stop <unit>
# 重新加载配置
$ systemctl reload <unit>
# 自启
$ systemctl enable <unit>
$ systemctl disable <unit>
# 屏蔽服务(防止手动或自动启动)
$ systemctl mask <unit>
$ systemctl unmask <unit>

$ systemctl is-active <unit>
$ systemctl is-enabled <unit>
$ systemctl is-failed <unit>

$ systemctl list-units --type=<service|target|socket>
# 失败的服务
$ systemctl list-units --state=failed

$ systemctl list-unit-files

# 获取当前目标
$ systemctl get-default
# 设置
$ systemctl set-default multi-user.target
# 设置默认后,还需要进行切换
$ systemctl isolate multi-user.target

# target 依赖关系
$ systemctl list-dependencies multi-user.target
$ systemctl list-dependencies graphical.target

# 分析
# 查看总启动时间
$ systemd-analyze time

# 查看各服务的启动时间
$ systemd-analyze blame

# 查看关键路径链
$ systemd-analyze critical-chain

# 查看图形化启动流程
$ systemd-analyze plot > boot.svg

# 生成详细的启动报告
$ systemd-analyze dump

# 验证单元文件语法
$ systemd-analyze verify /etc/systemd/system/myservice.service

# 生成启动跟踪图(需要 systemd-analyze 新版本)
$ systemd-analyze plot > boot.html

# 查看启动时间线
$ systemd-analyze dot | dot -Tsvg > timeline.svg

user-define daemon

Type用途适用场景Systemd 如何判断"启动成功"
simple前台进程大多数现代应用ExecStart 进程启动即成功
forking传统守护进程自动后台化的程序父进程退出 + PIDFile 指向子进程
oneshot一次性任务脚本/初始化任务进程执行完毕即成功
notify支持通知的应用需要精确就绪信号程序调用 sd_notify() 发送就绪信号
dbusD-Bus 服务注册 D-Bus 名称获取到指定的 D-Bus 名称
idle延迟启动图形应用类似 simple,但延迟到空闲时
exec简单执行特殊场景类似 simple,但更早标记为启动
simple/forking
plain

Type=simple: 直接跟踪 ExecStart 的进程
Systemd ──► ExecStart 进程(保持运行)◄── 直接跟踪

Type=forking: 通过 PIDFile 跟踪子进程
Systemd ──► 父进程 ──► fork() ──► 子进程(真正工作)
              │                    ▲
              ▼                    │
            退出                  PIDFile 指向这里

example

关于 daemon-user useradd -d /path/to/daemon-user -s /usr/bin/false -r daemon-user 禁止登录,但家目录有些时候会需要的。

ini
# Type=simple
[Unit]
Description=My Application
After=network.target

[Service]
Type=simple
User=daemon-user
Group=daemon-user
Environment="JAVA_OPTS=-XX:+UseG1GC"
ExecStart=/usr/bin/java $JAVA_OPTS -Xmx1G -jar /opt/myapp/app.jar

[Install]
WantedBy=multi-user.target

# Type=forking -----------------------------------------------------
[Unit]
Description=app service
Requires=network.target

[Service]
Type=forking
User=daemon-user
Group=daemon-user
Environment="PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin"
ExecStart=/path/to/script.sh
PIDFile=/path/to/app.pid

Restart=on-failure
RestartSec=10
StartLimitInterval=300  # 5 分钟内
StartLimitBurst=5       # 最多重启 5 次
# 资源限制(可选)
LimitNOFILE=65535
MemoryMax=2G

# 安全加固
NoNewPrivileges=true   # 禁止获取新权限
ProtectSystem=strict   # 只读挂载 /usr, /boot, /etc
ProtectHome=true       # 禁止访问 /home 目录
PrivateTmp=true        # 独立的 /tmp 目录
ProtectKernelTunables=true  # 禁止修改内核参数
ProtectKernelModules=true   # 禁止加载内核模块
ProtectControlGroups=true   # 禁止修改 cgroup

[Install]
WantedBy=multi-user.target

# -------------------------------------
# script.sh
#!/bin/bash
# 这里必须将程序置于后台
java -jar app.jar &> ./app.log &
echo $! > ./app.pid

系统优化

根据 server 使用场景调整系统参数。

sh
# dynamic adaptive systen tuning daemon
$ tuned
# command line tool for switching between different tuning profile
$ tuned-adm

$ tuned-adm list
Available profiles:
- accelerator-performance     - Throughput performance based tuning with disabled higher latency STOP states
- atomic-guest                - Optimize virtual guests based on the Atomic variant
- atomic-host                 - Optimize bare metal systems running the Atomic variant
- aws                         - Optimize for aws ec2 instances
- balanced                    - General non-specialized tuned profile
- cpu-partitioning            - Optimize for CPU partitioning
- cpu-partitioning-powersave  - Optimize for CPU partitioning with additional powersave
- default                     - Legacy default tuned profile
- desktop                     - Optimize for the desktop use-case
- desktop-powersave           - Optmize for the desktop use-case with power saving
- enterprise-storage          - Legacy profile for RHEL6, for RHEL7, please use throughput-performance profile
- hpc-compute                 - Optimize for HPC compute workloads
- intel-sst                   - Configure for Intel Speed Select Base Frequency
- laptop-ac-powersave         - Optimize for laptop with power savings
- laptop-battery-powersave    - Optimize laptop profile with more aggressive power saving
- latency-performance         - Optimize for deterministic performance at the cost of increased power consumption
- mssql                       - Optimize for Microsoft SQL Server
- network-latency             - Optimize for deterministic performance at the cost of increased power consumption, focused on low latency network performance
- network-throughput          - Optimize for streaming network throughput, generally only necessary on older CPUs or 40G+ networks
- openshift                   - Optimize systems running OpenShift (parent profile)
- openshift-control-plane     - Optimize systems running OpenShift control plane
- openshift-node              - Optimize systems running OpenShift nodes
- optimize-serial-console     - Optimize for serial console use.
- oracle                      - Optimize for Oracle RDBMS
- postgresql                  - Optimize for PostgreSQL server
- powersave                   - Optimize for low power consumption
- realtime                    - Optimize for realtime workloads
- realtime-virtual-guest      - Optimize for realtime workloads running within a KVM guest
- realtime-virtual-host       - Optimize for KVM guests running realtime workloads
- sap-hana                    - Optimize for SAP HANA
- sap-netweaver               - Optimize for SAP NetWeaver
- server-powersave            - Optimize for server power savings
- spectrumscale-ece           - Optimized for Spectrum Scale Erasure Code Edition Servers
- spindown-disk               - Optimize for power saving by spinning-down rotational disks
- throughput-performance      - Broadly applicable tuning that provides excellent performance across a variety of common server workloads
- virtual-guest               - Optimize for running inside a virtual guest
- virtual-host                - Optimize for running KVM guests
Current active profile: virtual-host

# --- ---
$ systemctl status tuned
# 推荐
$ tuned-adm recommend
# 设定优化配置
$ tuned-adm profile <profile>
# 当前配置
$ tuned-adm active
# 检查设定是否成功
$ tuned-adm verify
# 可能无法切换配置,尝试重启 tuned 服务。
$ systemctl restart tuned
# 检索 cup 是否支持优化设置,虚拟客机依赖于主机不支持。
$ cpupower frequency-info

启动过程

plaintext
Boot Loader(e.g.GRUB)

Kernel(vmlinuz)

intitial RAM disk - initramfs image

systemd(CentOS 6.x 使用 system V)

getty cmd line

x windows(x.org server)

-- https://www.cnblogs.com/ToTigerMountain/articles/18669860

https://blog.csdn.net/weixin_45264425/article/details/142436479#_499

从主机上电到完整系统(OS)加载:

  1. 硬件上电自检通过后,执行 BIOS 程序,选择磁盘执行其引导程序

  2. 硬件阶段:载入 BIOS/UEFI 的硬件信息与自检,并依据设定获取第一个可开机的装置

  3. 系统启动阶段:这个阶段大致分两种机制,一种传统 BIOS 读取硬盘,另一种通过 UEFI 读取硬盘。

    • BIOS:读取 MBR 的 boot loader(grub2, spfdisk 等程序)
    • UEFI:寻找系统内的开机分割槽(分割槽 System ID 为 EF00,文件系统 FAT),读取内部开机 loader。
  4. 依据 boot loader 的设定载入 Kernal,Kernal 会开始检测硬件与载入驱动程序;

    • 载入 Kernal file 与 initramfs 文件在内存中解压缩。
    • initramfs 会在内存模拟出根目录,提供 Kernal 相关的驱动程序模块。
    • 核心设备驱动程序完成的驱动硬件。
  5. 在硬件驱动成功后,Kernal 会主动调用 systemd 程序,并以 default.target 开机流程;

    • systemd 执行 sysinit.target 初始化系统及 basic.target 准备操作系统
    • systemd 启动 multi-user.target 下的本机与服务器服务。
    • systemd 执行 multi-user.target rc-local.service (加载 /etc/rc.local )
    • systemd 执行 getty.target 及登录服务(可配置 tty 数量)
    • systemd 执行 graphical.target 需要的服务 (如果启用的话)

fat, File Allocation Table

cifs, Common Internet FileSystem

ntfs, windows NT(new technology) FileSystem

系统日志

rsyslogd

rsyslogd, Rocket-fast SYStem LOG Daemon;收集、处理、过滤、转发系统日志和应用程序日志。取代 syslogd。二进制格式存储于/var/log/journal

sh

journalctl

journalctl,systemd-journald;systemd 管理的服务日志,提供过滤和查询。

sh
# journal service
$ journalctl

# 时间
$ journalctl --since '2026-01-01 00:00:00' --until '2026-01-10 00:00:00'
$ journalctl --since today
$ journalctl --since yesterday

# 日志级别
# emerg (0)
# alert (1)
# crit (2)
# err (3)
# warning (4)
# notice (5)
# info (6)
# debug (7)
$ journalctl -p err
$ journalctl -p 3
$ journalctl -p 3..5 # 范围

# 指定服务
$ journalctl -u <unit>
# 实时日志
$ journalctl -fu <unit>

# immediately jump to the end int the pager(尾页)
$ journalctl -e
# add message explanations where available(详细)
$ journalctl -x
# number of journal entries to show(行数)
$ journalctl -n 100

dmesg

dmesg, Diagnostic MESsage;lLinux显示和控制内核环形缓冲区(kernal ring buffer)内容工具。用于查看内核启动信息和运行时内核消息。

  • 内核环形缓冲区:内核在内存中维护的循环缓冲区,存储内核产生的消息。
sh
# print or control the kernal ring buffer
$ dmesg
# 指定级别
# emerg (0)
# alert (1)
# crit (2)
# err (3)
# warning (4)
# notice (5)
# info (6)
# debug (7)
$ dmesg -l err
$ dmesg -l 3
$ dmesg -l 1,2,3,4

内核模块

sh
# show the status of modules in the Linux Kernal
$ lsmod

# Show information about a Linux Kernal module
$ modinfo

$ modinfo xfs

# And and remove modules form the Linux Kernal
$ modprobe

# simple program to insert a module into the Linux Kernal
$ insmod

# simple program to remove a module form the Linux Kernal
$ rmmod

内核参数

/proc/sys 下记录了所有内核(Kernal)参数,存储于内存中掉电即失。

/etc/sysctl.conf 中调整参数可持久化。

sh
# 例如,修改 ping 无回应。(默认值0,回应 ping-pong)
$ echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all
# 持久生效
$ echo 'net.ipv4.icmp_echo_ignore_all=1' > /etc/sysctl.d/cus_ipv4.conf
# 调整生效,参考文档 /etc/sysctl.d/README*
$ service procps force-reload
# 或者
# read values form all system directories
$ sysctl -p /etc/sysctl.d/cus_ipv4.conf

系统救援

7-systemd 救援