13: Linux进程管理
2021-02-05 本文已影响0人
随便写写咯
1 进程和内存管理
内核功能:
进程管理
内存管理
文件系统管理
网络管理
驱动程序管理
安全管理
...
1.1 什么是进程
进程: 运行中的程序的一个副本, 是被载入内存的一个指令集合, 是资源分配的单位
进程ID(PID)号码被用来标记各个进程
进程运行身份UID, GID,和SELinux语境决定对文件系统的存取和访问权限
运行身份通常从执行进程的用户来继承
进程存在生命周期
进程创建:
init: 操作系统第一个进程, 从CentOS7后改为systemd
进程都由其父进程创建, 利用fork()系统调用, 采用 CoW: Copy On Write,写实复制机制
进程被加载到内存后, 由cpu负责运行
进程, 线程和携程
图片.png线程: 隶属于进程的一部分, 一个进程至少有一个线程, 多个线程间共享其进程资源, 会产生资源冲突
查看进程中的线程
- 线程信息可以通过/proc目录下, 对应的PID目录中的status文件查看
[16:50:42 root@centos-7-1 ~]#ls /proc
1 13 2 235 250 281 31 424 434 443 513 553 9 bus dma ioports kpageflags mpt self timer_list
10 132 20 238 255 282 32 425 435 45 537 6 95 cgroups driver irq loadavg mtrr slabinfo timer_stats
1061 14 21 24 256 283 33 428 438 460 541 60 961 cmdline execdomains kallsyms locks net softirqs tty
1063 15 22 240 276 284 365 429 439 462 544 7 967 consoles fb kcore mdstat pagetypeinfo stat uptime
1064 16 23 245 277 285 387 43 44 463 545 8 968 cpuinfo filesystems keys meminfo partitions swaps version
1068 17 232 246 278 286 4 430 440 465 546 806 acpi crypto fs key-users misc sched_debug sys vmallocinfo
1087 18 233 248 279 287 41 431 441 47 547 807 asound devices interrupts kmsg modules schedstat sysrq-trigger vmstat
11 19 234 249 280 30 423 432 442 5 548 810 buddyinfo diskstats iomem kpagecount mounts scsi sysvipc zoneinfo
[16:51:00 root@centos-7-1 ~]#cat /proc/1061/status | grep -i thread
Threads: 1
Speculation_Store_Bypass: thread vulnerable
1.2 进程结构
内核把进程放在叫做任务队列(task list)的双向循环链表中
链表中的每一项都是类型为task_struct, 称为进程控制块(Processing Control Block), PCB中包含一个具体进程的所有信息
1.3 进程相关概念
1.3.1 存储单位
Page Frame: 页框, 一个Page为4k
[17:28:42 root@centos-7-1 ~]#getconf -a | grep -i size
PAGESIZE 4096
PAGE_SIZE 4096
...
1.3.2 物理地址空间和虚拟地址空间
物理地址空间: 操作系统实际给进程分配的地址空间
虚拟地址空间: 进程认为自己独占整个操作系统空间
MMU: Memory Management Unit 负责虚拟地址转换为物理地址
程序在访问一个内存地址指向的内存时, CPU不是直接把这个地址送到内存总线上, 而是被送到MMU, 然后把这个内存地址映射到实际的物理内存地址上, 然后通过总线再去访问内存, 程序操作的地址称为虚拟内存地址
TLB: Transaction Lookaside Buffer, 后备缓冲器, 用于保存虚拟地址和物理地址映射关系的缓存
1.3.3 用户空间和内核空间
操作系统的内存空间分为用户空间(进程)和内核空间(内核)
每个进程认为自己独占整个用户空间
用户空间存放了进程的代码段, 数据, 以及堆栈信息
1.3.4 c代码和内存布局之间的对应关系
每个进程都包括5中不同的数据段
- 代码段: 用来存放可执行文件的操作指令, 也就是说它是可执行程序在内存中的镜像. 代码段需要防止在运行时被非法修改, 所以只准许读取操作, 而不允许写操作 -- 也就是代码段是不可写的
- 数据段: 用来存放可执行文件中已初始化的全局变量, 也就是存放程序静态分配的变量和全局变量
- BSS段: Block Started by Symbol, 以符号开始的块, BSS段包含了程中未初始化的全局变量, 在内存中BSS段全部置位0
- 堆(heap): 存放数组和对象, 堆是用于存放进程进行中被动态分配的内存段, 它的大小不固定, 可以扩张也可以缩减. 当进程调用malloc的函数分配内存时, 新分配的内存就被动态添加到堆上; 当利用free等函数释放内存时, 被释放的内存从堆中被剔除
- 栈: 栈是用户存放程序临时创建的局部变量, 也就是函数{}中定义的变量, 但不包括static声明的变量, static意味着在数据段中存放变量. 除此之外, 在函数被调用时, 其参数也会被压入发起调用的进程栈中, 并且待到调用结束后, 函数的返回值也会被存放回栈中. 由于栈区的后进先出特点, 所以栈区特别方便用来恢复/保存调用现场.
1.3.5 进程使用内存的问题
1.3.5.1 内存泄漏: Memory Leak
指程序中用malloc或new申请了一块内存, 但是没有用free或delete将内存释放, 导致这块内存一直处于占用状态
1.3.5.2 内存溢出: Memory Overflow
指程序中申请了固定的空间, 比如10M, 但是在这个空间写入了超过10M字节的数据, 这就是内存溢出
1.3.5.3 内存不足: OOM
Out of Memory, 一般在Java程勋中比较常见. 系统会选择一个进程将之杀死, 在日志中会看到Out of Memory信息
当JVM因为没有足够的内存来为对象分配空间并且垃圾回收器也已经没有空间可回收时, 就会抛出OOM, 因为该问题已经严重到不能被应用处理
OOM原因:
给应用分配的内存太少
应用程序使用内存过多, 并且没有及时释放, 此时就会造成内存泄漏或者内存溢出
解决方案:
1. 限制Java进程能使用的最大的堆区空间, 并且降低Java程序的worker数量, 从而降低内存使用
2. 给系统增加Swap空间
3. 设置内存参数, 不允许内存申请过量
不过不推荐设置内核参数敢于内存使用
内核参数的调整并不是最好的方案, 当出现内存问题时, 最好是要分析出问题的根源, 之后予以整改
内核参数调整:
Linux默认允许memory overcommit, 只要应用程序申请内存, 就会予以分配, 一旦内存超出, 会通过OOM Killer机制
挑选出一个进程杀死, 来释放空间, 如果内存空间还是不足, 就继续杀死进程
也可以通过设置内核参数 vm.panic_on_oom 使得发生OOM时自动重启系统.
但是, 无论是杀死进程还是重启系统都会造成业务中断
- vm.panic_on_oom: 决定系统出现OOM的时候, 要做的操作
0 - 默认值, 当出现OOM时, 触发OOM Killer杀死进程
1 - 程序在有cpuset, memory policy, memcg的约束情况下的OOM, 可以考虑不panic, 而是启动OOM Killer. 其他情况触发了 kernel panic, 那么系统直接重启
2 - 当出现OOM, 直接触发kernel panic, 系统直接重启
- Linux内核2.6之后, 允许通过内核参数 vm.overcommit_memory 来禁止memory overcommit
0 - Heuristic overcommit Handling, 默认值, 允许overcommit, 但是明目张胆的overcommit会被拒绝, 比如malloc一次性申请的内存大小超过了系统总内存. Heuristic的意思是试探式的, 内核利用某种算法猜测内存申请是否合理, 如果认为不合理就拒绝overcommit
1 - Always overcommit, 允许overcommit, 对内存申请都允许. 内核执行无内存过量使用处理. 使用这个设置会增大内存超载的可能性, 但也可以增强大量使用内存任务的性能
2 - Don't overcommit, 禁止overcommit. 内存拒绝等于或者大于总可用swap空间大小以及overcommit_ratio指定的物理RAM比例的内存请求. 如果希望减小内存过度使用的风险, 这个参数是最好的
- 内核设有一个阈值, 申请的内存总数超过这个阈值就算overcommit, 在/proc/meminfo中可以看到
[19:03:28 root@centos-7-1 ~]#grep -i commit /proc/meminfo
CommitLimit: 2594988 kB
Committed_AS: 216008 kB
CommitLimit 就是overcommit的阈值, 申请的内存总数超过CommitLimit的数值就被认为overcommit
此值是通过内核参数vm.overcommit_ratio或vm.overcommit_kbytes间接设置的
- vm.overcommit_ratio是内核参数, 默认为50, 表示物理内存的50%. 如果不想用此比例, 也可以直接指定内存的字节数大小, 通过另一个内核参数vm.overcommit_kbytes指定
/proc/meminfo中的Committed_AS表示所有进程已经申请的内存总大小, 是已经申请了的, 而非已经分配的.
如果Commited_AS超过了CommitLimit就表示发生了overcommit, 超出越多表示overcommit越严重
Committed_AS代表了如果要保证不发生OOM, 那么Committed_AS不能超过CommittedLimit的大小
1.4 进程状态
图片.png进程的基本状态
创建状态: 进程在创建时需要申请一个空白PCB, 向其中填写控制和管理进程的信息, 完成资源分配. 如果创建工作无法完成, 比如资源无法满足, 就无法被调度运行, 把此时进程所处状态称为创建状态
就绪状态: 进程已经准备好, 已分配到所需资源, 只要分配的CPU就能够立即运行
执行状态: 进程处于就绪状态被调度后, 进程进入执行状态
阻塞状态: 正在被执行的进程, 由于某些事件(I/O请求, 申请缓存区失败)而暂时无法运行, 进程受到阻塞. 在满足请求时进入就绪状态等待系统调用
终止状态: 进程结束, 或出现错误, 或被系统终止, 进入终止状态, 无法再执行
运行态: running
就绪态: ready
睡眠态: 分为两种, 可中断睡眠(睡眠状态可以被中断, 转为其他状态); interruptable, 不可中断睡眠(无法干预, 达到一定状态会自动唤醒); uninterruptable
停止态: stopped, 暂停于内存, 但不会被调度, 除非手动启动
僵尸态(Z): zombie, 结束的进程, 进程运行完,但是没有父进程将其关闭,或者子进程运行完, 父进程还没有运行结束. 可以直接杀死父进程或者恢复父进程都可以关闭僵尸态的子进程
进程间的转换
运行 --> 就绪:
1. 程序进程需要占用CPU的时间过长, 而系统分配给进程占用CPU的时间是有限的, 进程就会在运行和就绪态间切换
2. 在采用抢占式优先级调度算法的系统中, 当有更高优先级的进程要运行时, 该进程就被迫让出CPU, 该进程便由执行状态转变为就绪状态
就绪 --> 运行:
运行的进程的时间片用完, 调度就转到就绪队列中选择合适的进程分配CPU
运行 --> 阻塞:
正在执行的进程因发生某等待事件而无法执行, 则进程由执行状态变成阻塞状态, 如发生了I/O请求
阻塞 --> 就绪:
进程所等待的事件已经发生, 就进入就绪队里
- 以下两种状态是不可能发生的
阻塞 --> 运行:
即使给阻塞进程分配CPU, 也无法执行, 操作系统在进行调度时不会从阻塞队列进行挑选, 而是从就绪队列中选取
就绪 --> 阻塞:
就绪态根本没有执行, 也就谈不上阻塞态
1.5 LRU算法
LRU: Least Recently Used, 释放内存
可以利用缓存技术, 将硬盘中的数据放入内存, 来加快访问速度; 但是, 内存的空间是有限的, 就需要相应的算法来控制数据在内存中的存储情况 - LRU
近期被访问的数据会按照先进先出的原则, 存放内存, 如果某段时间内, 某个数据被访问的次数最少, 就被会从内存删除, 而内存只保留被频繁访问的数据
1.6 IPC 进程间通信
IPC: Inter Process Communication
- 同一主机
pipe 管道, 单向传输
socket 套接字文件, 双向传输
Memory-mapped file 文件映射, 将文件中的一段数据映射到物理内存, 多个进程共享这片内存
shm shared memory 共享内存
signal 信号
Lock 对资源上锁, 如果资源已被某个进程锁住, 则其他进程想修改甚至读取这些资源, 都将被阻塞, 直至锁被打开
smeaphore 信号量, 一种计数器
- 不同主机
RPC: Remote Procedure Call
MQ: 消息队列, 生产者和消费者, 如, Kafka, RabbitMQ, ActiveMQ
1.7 进程优先级
CentOS优先级
图片.png系统优先级: 0-139, 数字越小, 优先级越高, 各有140个运行队里和过期队列
实时优先级: 99-0, 值越大优先级越高
nice值: -20到19, 对应系统优先级100-139
2 进程管理和性能相关工具
Linux系统的状态的查看及管理工具: pstree, ps, pidof, pgrep, top, htop, glance, pmap, vmstat, dstat, kill, pkill, job, bg, fg, nohup
2.1 进程树 pstree
pstree, 树形结构显示进程的父子关系, 常用pstree, pstree -p(显示PID)
案例: 显示以某个用户身份运行的程序
21:20:23 root@centos-7-1 ~]#pstree postfix
pickup
qmgr
2.2 进程信息ps
查看进行状态, 默认显示当前终端中的进程, Linux系统各进程的相关信息均保存在/proc/PID目录下的各文件中
[19:59:40 root@centos-7-1 ~]#ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 2 0.0 0.0 0 0 ? S 16:35 0:00 [kthreadd]
USER: 进程由哪个用户运行
PID: 该进程的PID
%CPU: 进程所占用的CPU百分比
%MEM: 进程所占用内存的百分比
VSZ: 进程被分配的虚拟内存
RSS: 实际分配的内存
TTY: 进程运行终端信息
STAT: 进程状态信息
START: 进程启动时间
TIME: 进程运行的时间
COMMAND: 进程运行的命令
进程的STAT状态:
R: running, 运行态
S: interruptable sleeping, 可中断睡眠
D: uninterruptable sleeping, 不可中断睡眠
T: stopped
Z: zombie
+: 前台进程
l: 多线程进程
L: 内存分页并带锁
N: 低优先级进程
<: 高优先级进程
s: session leader, 会话(子进程)发起者
I: idle kernel thread, CentOS 8新特性
常用组合
ps aux: 显示信息更全面
ps -ef
ps axo pid,cmd,psr,ni,pri,trprio # 查看进程的特定属性
ni: nice值
pri: priority优先级
rtprio: 实时优先级
psr: processor CPU编号
[20:10:27 root@centos-7-1 ~]#ps axo pid,cmd,psr,ni,pri,rtprio
PID CMD PSR NI PRI RTPRIO
1 /usr/lib/systemd/systemd -- 0 0 19 -
2 [kthreadd] 0 0 19 -
4 [kworker/0:0H] 0 -20 39 -
6 [ksoftirqd/0] 0 0 19 -
7 [migration/0] 0 - 139 99
案例: 构建僵尸态, 并处理
一般僵尸态的进程已经运行结束, 不会占用太多资源, 一般不需要处理
1. 执行bash, 开启子进程
─sshd(807)───sshd(1064)───bash(1068)───bash(26492)───pstree(26505)
# 此时, 26492的父进程为1608
2. 将父进程设为停止态
[20:21:07 root@centos-7-1 ~]#ps aux | grep 1068
root 1068 0.0 0.2 116048 2684 pts/0 Ts 16:50 0:00 -bash # T: 停止态
3. 查看此时的父子进程状态
[20:21:15 root@centos-7-1 ~]#ps auxf # f参数可查看父子进程关系
root 1068 0.0 0.2 116048 2684 pts/0 Ts 16:50 0:00 \_ -bash # 此时父进程处于T, 停止态
root 26492 0.0 0.2 115940 2480 pts/0 S 20:19 0:00 \_ bash # 此时子进程处于可中断睡眠
root 26508 0.0 0.1 155608 1948 pts/0 R+ 20:22 0:00 \_ ps auxf
4. kill子进程
[20:22:10 root@centos-7-1 ~]#kill -9 26492
5. 切换到另一个终端, 查看进程状态
[20:25:45 root@centos-7-1 ~]#ps auxf
root 1068 0.0 0.2 116048 2684 pts/0 Ts 16:50 0:00 | \_ -bash
root 26492 0.0 0.0 0 0 pts/0 Z+ 20:19 0:00 | \_ [bash] <defunct> # 子进程处于Z状态, 同时可以看到vss和rss都为0,因此僵尸态本身并不太消耗内存空间
6. 将父进程恢复, 即可关闭僵尸态子进程
[20:31:08 root@centos-7-1 ~]#kill -18 1068
7. 或者直接杀死父进程
kill -9 父进程PID
案例: 查看指定属性
ps axo o 选项可以用来查看指定的属性
[21:21:46 root@centos-7-1 ~]#ps axo pid,cmd,pri,ni
PID CMD PRI NI
1 /usr/lib/systemd/systemd -- 19 0
案例: 查看指定的属性, 并按照指定列正序排序
[21:21:51 root@centos-7-1 ~]#ps axo pid,cmd,ni,pri,%cpu,%mem k %cpu
PID CMD NI PRI %CPU %MEM
1 /usr/lib/systemd/systemd -- 0 19 0.0 0.3
2 [kthreadd] 0 19 0.0 0.0
案例: 查看指定的属性, 并按照指定列倒序排序
[21:23:17 root@centos-7-1 ~]#ps axo pid,cmd,ni,pri,%cpu,%mem k -%cpu
PID CMD NI PRI %CPU %MEM
546 /usr/bin/vmtoolsd 0 19 0.2 0.6
26532 [kworker/0:2] 0 19 0.1 0.0
案例: --sort 参数也可以实现排序
正序:
[21:24:40 root@centos-7-1 ~]#ps axo pid,cmd,ni,pri,%cpu,%mem --sort %cpu
倒序:
[21:24:40 root@centos-7-1 ~]#ps axo pid,cmd,ni,pri,%cpu,%mem --sort -%cpu
2.3 查看进程信息 prtstat
来自prmisc包
显示内容更全
[21:26:11 root@centos-7-1 ~]#prtstat 26512
Process: bash State: S (sleeping)
CPU#: 0 TTY: 136:1 Threads: 1
Process, Group and Session IDs
Process ID: 26512 Parent ID: 26510
Group ID: 26512 Session ID: 26512
T Group ID: 28588
Page Faults
This Process (minor major): 2643 0
Child Processes (minor major): 14568 0
CPU Times
This Process (user system guest blkio): 0.10 0.03 0.00 0.00
Child processes (user system guest): 0.12 0.89 0.00
Memory
Vsize: 118 MB
RSS: 2527 kB RSS Limit: 18446744073709 MB
Code Start: 0x400000 Code Stop: 0x4dd524
Stack Start: 0x7fff03ef8ba0
Stack Pointer (ESP): 0x7fff03ef8658 Inst Pointer (EIP): 0x7f454165446c
Scheduling
Policy: normal
Nice: 0 RT Priority: 0 (non RT)
2.4 设置和调整优先级
只有静态优先级可以手动调整: 100-139
进程默认启动时的nice值为0, 而系统优先级为120
只有root用户才能降低nice值, 来提高进程的优先级
案例: 手动提高nice优先级
[21:29:20 root@centos-7-1 ~]#nice -n -1 ping 127.0.0.1
[21:28:44 root@centos-7-1 ~]#ps axo pid,cmd,ni
PID CMD NI
28707 ping 127.0.0.1 -1
运行中的进程也可以修改其nice优先级, 方法和上述手动方法一致(换成renice命令即可)
2.5 搜索进程
2.5.1 pgrep
相当于ps aux后再用grep搜索
常用选项:
-u uid: effective user, 生效者, 当命令的二进制文件有suid权限时, 其他用户运行此命令时, 真正的生效者是文件的owner, 而不是发起命令的用户, pkill命令的原理也一样
-U uid: real user, 真正发起运行命令者
-t terminal: 与指定终端相关的进程
-l: 显示进程名称
-a: 显示完整格式的进程名
-P pid: 显示指定进程的子进程
2.5.2 pidof
查看某个进程对应的进程PID, 显示所有的PID
[21:38:07 root@centos-7-1 ~]#pidof bash
26512 1068
-x: 按照运行的脚本名称查看其PID
当给脚本加了执行权限, 用/路径/脚本名去执行时, 执行脚本的程序就是/bin/bash, 如果想查看具体某个脚本的执行PID, 需要用-x选项
[21:52:51 root@centos-7-1 ~]#./ping.sh
[21:51:25 root@centos-7-1 ~]#pidof -x ping.sh
29870
2.6 负载查询 uptime
/proc/uptime 包含两个值, 单位是秒
- 系统启动时长
- 空闲进程总时长(按照总的CPU核数计算)
[21:54:22 root@centos-7-1 ~]#cat /proc/uptime
20264.65 20035.18
uptime和w显示以下内容
- 当前时间
- 系统已启动的时间
- 当前线上人数
- 系统平均负载(1,5,15分钟内的平均负载, 一般不会超过1, 超过5时建议警报)
[21:51:30 root@centos-7-1 ~]#uptime
21:54:22 up 5:18, 2 users, load average: 0.00, 0.01, 0.05
系统平均负载: 指在特定时间间隔内, 运行队列中的平均进程数, 通常每个CPU内核的当前活动进程数不大于3, 那么表示系统的性能良好, 如果每个CPU的内核任务数大于5, 那么此主机的性能有严重问题
比如: 只有一个双核CPU的Linux服务器, 当Load Avarage为6的时候就说明机器已经被充分使用
2.7 显示CPU相关统计信息 mpstat
显示CPU相关信息
来自sysstat包
[22:19:45 root@centos-7-1 ~]#mpstat
Linux 3.10.0-1127.el7.x86_64 (centos-7-1.prac) 02/04/2021 _x86_64_ (1 CPU)
10:19:51 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
10:19:51 PM all 0.14 0.03 0.31 0.01 0.00 0.02 0.00 0.00 0.00 99.49
%steal: 被盗取的CPU消耗的百分比, 比如虚拟机消耗的CPU时间分片
2.8 查看进程实时状态 top
top提供实时查看进程状态
排序:
P: 以占据的CPU百分比排序, %CPU
M: 以占据的内存百分比排序, %MEM
T: 累计占据CPU时长, TIME+
[22:19:51 root@centos-7-1 ~]#top
top - 22:20:45 up 5:45, 2 users, load average: 0.09, 0.06, 0.06
Tasks: 103 total, 1 running, 102 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 995684 total, 374068 free, 129596 used, 492020 buff/cache
KiB Swap: 2097148 total, 2097148 free, 0 used. 693492 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
31332 root 20 0 162124 2148 1532 R 6.2 0.2 0:00.01 top
1 root 20 0 125496 3916 2600 S 0.0 0.4 0:04.91 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd
htop: 增强版top命令
2.9 查看内存 free
[22:33:58 root@centos-7-1 ~]#free -h
total used free shared buff/cache available
Mem: 972M 126M 360M 7.6M 485M 675M
Swap: 2.0G 0B 2.0G
2.10 进程对应的内存映射 pmap
当某个程序经常占用大量内存时, 可以通过pmap查看程序中对应的每个模块占用的内存大小, 来具体分析
[21:56:33 root@centos-7-1 ~]#pidof top
32151
[22:37:27 root@centos-7-1 ~]#pmap 32151
32151: top
0000000000400000 96K r-x-- top
0000000000617000 4K r---- top
0000000000618000 8K rw--- top
000000000061a000 156K rw--- [ anon ]
0000000000d4b000 364K rw--- [ anon ]
00007f58f14fc000 48K r-x-- libnss_files-2.17.so
2.11 虚拟内存信息 vmstat
[22:37:31 root@centos-7-1 ~]#vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
2 0 0 368372 2080 495080 0 0 11 13 35 58 0 0 99 0 0
vmstat 1 3
每一秒钟运行一次, 一共运行3次
si和so都是以内存为参照物, 当内存空间不足, 会利用swap空间, 把数据从内存写到swap, 这时对于内存来说, 数据是从内存写到swap, 因此是出, 那么so的数值就是增大
bi和bo一样, 也是以内存为参照物, 数据流向内存, 那么si或者bi就增加, 数据从内存流出, bo和so增加
2.12 统计CPU和设备I/O iostat
来自sysstat包, 可以查看磁盘I/O和CPU负载情况
iostat 1 3
[22:42:03 root@centos-7-1 ~]#iostat 1 3
Linux 3.10.0-1127.el7.x86_64 (centos-7-1.prac) 02/04/2021 _x86_64_ (1 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
0.15 0.03 0.32 0.01 0.00 99.49
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
sda 0.77 10.34 12.58 230109 279951
scd0 0.00 0.05 0.00 1028 0
avg-cpu: %user %nice %system %iowait %steal %idle
0.00 0.00 1.00 0.00 0.00 99.00
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
sda 0.00 0.00 0.00 0 0
scd0 0.00 0.00 0.00 0 0
avg-cpu: %user %nice %system %iowait %steal %idle
1.00 0.00 0.00 0.00 0.00 99.00
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
sda 0.00 0.00 0.00 0 0
scd0 0.00 0.00 0.00 0 0
2.13 系统资源统计 dstat(cpu, 磁盘, 网络, swap)
CentOS7上来自dstat包, CentOS8上来自pcp-system-tools, 用来代替vmstat, iostat命令
默认就是不断刷新, 实时监控, cpu, 磁盘I/O和网络I/O
[22:53:13 root@centos-7-1 ~]#dstat
You did not select any stats, using -cdngy by default.
----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system--
usr sys idl wai hiq siq| read writ| recv send| in out | int csw
0 0 99 0 0 0| 10k 13k| 0 0 | 0 0 | 36 58
0 0 100 0 0 0| 0 0 | 332B 5794B| 0 0 | 71 103
0 1 99 0 0 0| 0 0 | 438B 648B| 0 0 | 60 93
2.14 监视磁盘I/O iotop
查看磁盘I/O, 更专业, 来自iotop包, 会显示磁盘I/O具体是被哪个程序所消耗
[22:55:11 root@centos-7-1 ~]#iotop
Total DISK READ : 0.00 B/s | Total DISK WRITE : 0.00 B/s
Actual DISK READ: 0.00 B/s | Actual DISK WRITE: 0.00 B/s
TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND
1 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % systemd --switched-root --system --deserialize 22
2 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [kthreadd]
2.15 显示网络带宽使用情况 iftop
显示网络情况
[22:56:30 root@centos-7-1 ~]#iftop
interface: eth0
IP address is: 10.0.0.237
MAC address is: 00:0c:29:54:b7:78
Press H or ? for help 12.5Kb 25.0Kb 37.5Kb 50.0Kb 62.5Kb
mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqvqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqvqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqvqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqvqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
centos-7-1.prac => 10.0.0.1 9.03Kb 7.93Kb 11.6Kb
<= 1.80Kb 1.62Kb 1.67Kb
centos-7-1.prac => public1.alidns.com 0b 0b 54b
<= 0b 0b 104b
2.16 查看网络实时吞吐量 nload
Device eth0 [10.0.0.237] (1/2):
====================================================================================================================================================================================
Incoming:
Curr: 3.80 kBit/s
Avg: 2.95 kBit/s
Min: 2.54 kBit/s
Max: 3.80 kBit/s
Ttl: 41.64 MByte
Outgoing:
Curr: 11.30 kBit/s
Avg: 24.73 kBit/s
Min: 5.13 kBit/s
Max: 58.30 kBit/s
Ttl: 6.48 MByte
2.17 综合监控工具 glances
图片.png2.18 查看进程打开文件 lsof
list open files: 查看当前系统文件的工具
在Linux环境下, 一切皆是文件, 用户通过文件不仅可以访问常规数据, 还可以访问网络连接和硬件如tcp和udp套接字等, 系统在后台都为该应用程序分配了一个文件描述符
查看某个端口号被哪个进程占用
[23:11:03 root@centos-7-1 ~]#lsof -i:25
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
master 961 root 13u IPv4 19668 0t0 TCP localhost:smtp (LISTEN)
master 961 root 14u IPv6 19669 0t0 TCP localhost:smtp (LISTEN)
案例: 利用lsof恢复正在使用中的误删除的文件
1. messages日志文件是一直被rsyslogd占用的
[23:14:36 root@centos-7-1 ~]#lsof /var/log/messages
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
rsyslogd 810 root 6w REG 8,2 704472 34092214 /var/log/messages
2. 删除messages文件
[23:15:58 root@centos-7-1 ~]#rm -rf /var/log/messages
[23:16:33 root@centos-7-1 ~]#ls -l /var/log/messages
ls: cannot access /var/log/messages: No such file or directory
3. 删除后在lsof的输出中仍能看到, 状态为deleted
[23:16:42 root@centos-7-1 ~]#lsof | grep /var/log/messages
rsyslogd 810 root 6w REG 8,2 704472 34092214 /var/log/messages (deleted)
in:imjour 810 813 root 6w REG 8,2 704472 34092214 /var/log/messages (deleted)
rs:main 810 814 root 6w REG 8,2 704472 34092214 /var/log/messages (deleted)
4. 通过fd文件描述符来恢复数据
[23:17:09 root@centos-7-1 ~]#ls /proc/810/fd
0 1 2 3 4 5 6 7 8 9
[23:19:17 root@centos-7-1 ~]#ls /proc/810/fd -l
total 0
lr-x------ 1 root root 64 Feb 4 16:35 0 -> /dev/null
l-wx------ 1 root root 64 Feb 4 16:35 1 -> /dev/null
l-wx------ 1 root root 64 Feb 4 16:35 2 -> /dev/null
lr-x------ 1 root root 64 Feb 4 16:35 3 -> anon_inode:inotify
lrwx------ 1 root root 64 Feb 4 16:35 4 -> socket:[19054]
lr-x------ 1 root root 64 Feb 4 16:35 5 -> /run/log/journal/faf6cab1d01a401daa5c2e37cab6e4fa/system.journal
l-wx------ 1 root root 64 Feb 4 16:35 6 -> /var/log/messages (deleted) # fd6就是被我们删除的messages文件使用的文件描述符
l-wx------ 1 root root 64 Feb 4 16:35 7 -> /var/log/cron
l-wx------ 1 root root 64 Feb 4 16:35 8 -> /var/log/secure
l-wx------ 1 root root 64 Feb 4 16:35 9 -> /var/log/maillog
[23:19:27 root@centos-7-1 ~]#cat /proc/810/fd/6 > /var/log/messages # 读出来文件描述符, 追加到messages里
[23:20:09 root@centos-7-1 ~]#ls -l /var/log/messages
-rw-r--r-- 1 root root 704541 Feb 4 23:20 /var/log/messages
2.19 信号发送 kill
kill: 可用来向进程发送控制信号, 以实现对进程管理, 每个信号对应一个数字, 信号名称以SIG开头, 不区分大小写
- 查看当前系统可用信号
kill -l
trap -l
- 常用信号
1 --> SIGHUP 无须关闭进程而让其重读配置文件
2 --> SIGINT 中止正在运行的进程, 相当于ctrl+c
3 --> SIGQUIT 相当于ctrl + \
9 --> SIGKILL 强制杀死正在运行的进程
15 --> SIGTERM 终止正在运行的进程, 默认信号
18 --> SIGCONT 继续运行
19 --> SIGSTOP 后台休眠
- 向进程发送信号
按PID
kill -1 PID
按进程名称
killall 进程名称
按照模式
pkill [options] PATTERN
常用选项:
-SIGNAL
-u uid: effective user, 生效者
-U uid: real user, 真正发起运行命令者
-t terminal: 与指定终端相关的进程
-l: 显示进程命名(pgrep可用)
-a: 显示完整格式的进程名(pgrep可用)
-P pid: 显示指定进程的子进程
- 0 信号, 可以用来对程序进行健康性检查
killall -0 ping
echo $0
0
killall -0 ping
ping: no process found
echo $0
1
此方式有局限性, 即使进程处于僵尸态或者停止态, 0信号仍然认为进程是健康的
2.20 作业管理
Linux的作业控制
前台运行: 通过终端启动, 且启动后一直占据终端
后台运行: 可通过终端启动, 但启动后立即转入后台运行, 释放终端资源
图片.png
让作业运行于后台
1. 运行中的作业: ctrl + z, 让其处于stop状态, 停止在后台
2. 尚未启动的作业: CMD &
CMD & 启动的后台作业虽然会被送往后台运行, 但是其依然与终端有关, 退出终端, 将关闭后台作业
如果希望送往后台后, 与终端脱离关系, 可以使用下面命令
使用nohup运行命令后, 如果终端关闭, 那么systemd会变成其父进程, systemd是不会被关闭的, 所以即使关闭了终端,命令还会执行
nohup CMD &> /dev/null &
查看当前终端所有作业
jobs
作业控制
fg %JOBNUMBER: 把指定的后台作业调回前台
bg %JOBNUMBER: 把送往后台的作业在后台继续运行
kill %JOBNUMBER: 终止指定的作业
2.21 并行运行
利用后台执行, 实现并行功能, 即同时运行多个进程, 提高效率
方法1: 在脚本中实现
cat all.sh
f1.sh&
f2.sh&
f3.sh&
方法2:
(f1.sh&);(f2.sh&);(f3.sh&)
方法3:
f1.sh&f2.sh&f3.sh&
案例: 实现并行扫描网段的主机
#!/bin/bash
NET=10.0.0
for i in {1..254}; do
{
ping -c1 -W1 ${NET}.${i} &> /dev/null && echo "${NET}.$i is up" || echo "${NET}.$i is down"
}&
done
wait # 后台命令执行结束, 返回终端, 否则执行完会卡住, 还要手动退出执行
~