Linux(进阶篇),此时就会造成内存泄露


一、进程

1 进程和内存管理

1.1 进程和线程的区别

  • 线程是程序执行的最小单位,而进程是操作系统分配资源的最小单位
  • 一个进程由一个或多个线程组成,线程是一个进程中代码的不同执行路线
  • 进程之间相互独立,但同一进程下的各个线程之间共享程序的内存空间(包括代码段、数据集、堆等)及一些进程级的资源(如打开文件和信号),某进程内的线程在其它进程不可见
  • 调度和切换:线程上下文切换比进程上下文切换要快得多

 

1.2 查看进程中的线程 

grep -i threads /proc/PID/status

 

1.3 进程使用内存管理问题

1.3.1 内存泄漏:Memory Leak

指程序中用malloc或new申请了一块内存,但是没有用free或delete将内存释放,导致这块内存一直处于占用状态

1.3.2 内存溢出:Memory Overflow

指程序申请了10M的空间,但是在这个空间写入10M以上字节的数据,就是溢出

1.3.3 内存不足:OOM(Out Of Memory)

原因

  • 给应用分配内存太少:比如虚拟机本身可使用的内存(一般通过启动时的VM参数指定)太少
  • 应用用的太多,并且用完没释放,浪费了。此时就会造成内存泄露或者内存溢出

使用的解决办法:

  • 限制java进程的max heap,并且降低java程序的worker数量,从而降低内存使用
  • 给系统增加swap空间

 

1.4 进程状态

  • 运行态:running
  • 就绪态:ready
  • 睡眠态:分为两种,可中断:interruptable,不可中断:uninterruptable
  • 停止态:stopped,暂停于内存,但不会被调度,除非手动启动
  • 僵死态:zombie,僵尸态,结束进程,父进程结束前,子进程不关闭,杀死父进程可以关闭僵死态的子进程

范例:僵尸态

#父进程和子进程的创建
[root@rocky01 ~]# bash
[root@rocky01 ~]# echo $BASHPID
2267
[root@rocky01 ~]# echo $PPID
2209
[root@rocky01 ~]# pstree -p |grep 2209
           |-sshd(948)-+-sshd(2195)---sshd(2208)---bash(2209)---bash(2267)-+-grep(2289)

#将父进程设为停止态
[root@rocky01 ~]# kill -19 2209
#杀死子进程,进入僵尸态
[root@rocky01 ~]# kill -9 2267
#可以看到子进程STAT为Z,表示为僵尸态
[root@rocky01 ~]# ps aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root        2267  0.0  0.0      0     0 pts/0    Z+   20:25   0:00 [bash] <defunct>
root        2295  0.0  0.1  58752  3972 pts/1    R+   20:27   0:00 ps aux

#解决方法
#方法一:恢复父进程
[root@rocky01 ~]# kill -19 2209
#方法二:杀死父进程
[root@rocky01 ~]# kill -9 2209

范例:孤儿进程

[root@rocky01 ~]# (sleep 100 &)
[root@rocky01 ~]# pstree -p |grep sleep
           |-sleep(2342)

 

1.5 LRU算法

LRU:Least Recently Used 近期最少使用算法(喜新厌旧),释放内存

 

1.6 IPC进程间通信

范例:利用管道文件实现 IPC

[root@rocky01 ~]# mkfifo test.fifo
[root@rocky01 ~]# ll test.fifo
prw-r--r-- 1 root root 0 Aug 15 20:51 test.fifo
[root@rocky01 ~]# echo Willoneday > test.fifo
#此时为等待读入状态,读取数据后才会调到命令提示符

#在另一个终端可以从文件中读取数据
[root@rocky01 ~]# cat test.fifo
Willoneday

 

1.7 进程优先级

  • 系统优先级: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 [ OPTION ] [ PID | USER ]

常用选项:

  • -p 显示PID
  • -T 不显示线程thread,默认显示线程
  • -u 显示用户切换
  • -H pid 高亮显示指定进程及其前辈进程

 

2.2 ps 进程信息

ps 即 process state,显示有关活动进程信息,Linux系统各进程的相关信息均保存在/proc/PID目录下的各文件中

支持三种选项:

  • UNIX选项 如: -A -e
  • GNU选项 如: --help
  • BSD选项 如: a

格式:ps [ OPTION ]...

常用选项:

  • a 选项包括所有终端中的进程
  • x 选项包括不链接终端的进程
  • u 选项显示进程所有者的信息
  • f 选项显示进程树,相当于 --forest
  • k sort 属性 对属性排序,属性前加 - 表示倒序
  • o 属性… 选项显示定制的信息 pid、cmd、%cpu、%mem
  • L 显示支持的属性列表
  • -C cmdlist 指定命令,多个命令用,分隔
  • -L 显示线程
  • -e 显示所有进程,相当于-A
  • -f 显示完整格式程序信息
  • -F 显示更完整格式的进程信息
  • -H 以进程层级格式显示进程相关信息
  • -u userlist 指定有效的用户ID或名称
  • -U userlist 指定真正的用户ID或名称
  • -g gid或groupname 指定有效的gid或组名称
  • -G gid或groupname 指定真正的gid或组名称
  • -p pid 显示指pid的进程
  • --ppid pid 显示属于pid的子进程
  • -t ttylist 指定tty,相当于 t
  • -M 显示SELinux信息,相当于Z

2.2.1 ps 输出信息

  • C :  ps -ef 显示列 C 表示cpu利用率
  • VSZ: Virtual memory SiZe,虚拟内存集,线性内存
  • RSS: ReSident Size, 常驻内存集
  • STAT:进程状态
  • R:running
  • S: interruptable sleeping
  • D: uninterruptable sleeping
  • T: stopped
  • Z: zombie
  • +: 前台进程
  • l: 多线程进程
  • L:内存分页并带锁
  • N:低优先级进程
  • <: 高优先级进程
  • s: session leader,会话(子进程)发起者
  • I(大写i):Idle kernel thread,CentOS 8 新特性
  • ni: nice值
  • pri: priority 优先级
  • rtprio: 实时优先级
  • psr: processor CPU编号

范例:查看进程的特定属性

[root@rocky01 ~]# ps axo pid,cmd,%mem,%cpu
    PID CMD                         %MEM %CPU
      1 /usr/lib/systemd/systemd --  0.2  0.0
      2 [kthreadd]                   0.0  0.0
      3 [rcu_gp]                     0.0  0.0
      4 [rcu_par_gp]                 0.0  0.0
      6 [kworker/0:0H-events_highpr  0.0  0.0
      9 [mm_percpu_wq]               0.0  0.0
...省略...

范例:按CPU利用率倒序排序

[root@rocky01 ~]# ps aux k -%cpu
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         927  0.2  0.8 568912 31904 ?        Ssl  Aug29  13:31 /usr/libexec/platform-python -Es /usr
root       22116  0.1  0.0      0     0 ?        I    19:16   0:08 [kworker/0:1-mm_percpu_wq]
root           1  0.0  0.2 172768 11204 ?        Ss   Aug29   0:09 /usr/lib/systemd/systemd --switched-r
root           2  0.0  0.0      0     0 ?        S    Aug29   0:00 [kthreadd]
...省略...

面试题:找到未知进程的执行程序文件路径

[root@rocky01 ~]# ll /proc/16642/exe
lrwxrwxrwx 1 root root 0 Aug 29 23:24 /proc/16642/exe -> /data/httpd-2.4.54/bin/httpd

 

2.3 prtstat 查看进程信息

可以显示进程信息,来自于psmisc包

格式:prtstat [ options ] PID ..

选项:-r raw格式显示

[root@rocky01 ~]# prtstat -r 16642
         pid: 16642          	                  comm: httpd
       state: S              	                  ppid: 1
        pgrp: 16642          	               session: 16642
      tty_nr: 0              	                 tpgid: -1
       flags: 404040         	                minflt: 307
     cminflt: 0              	                majflt: 0
     cmajflt: 0              	                 utime: 290
       stime: 331            	                cutime: 0
      cstime: 0              	              priority: 20
        nice: 0              	           num_threads: 1
 itrealvalue: 0              	             starttime: 21243019
       vsize: 119353344      	                   rss: 1365
      rsslim: 18446744073709551615	             startcode: 4194304
     endcode: 4967936        	            startstack: 140721176867168
     kstkesp: 0              	               kstkeip: 0
       wchan: 0              	                 nswap: 0
      cnswap: 0              	           exit_signal: 17
   processor: 1              	           rt_priority: 0
      policy: 0              	 delayaccr_blkio_ticks: 0
  guest_time: 0              	           cguest_time: 0

 

2.4 设置和调整进程优先级

进程优先级调整

  • 静态优先级:100-139
  • 进程默认启动时的nice值为0,优先级为120
  • 只有根用户才能降低nice值(提高优先性)

2.4.1 nice 以指定的优先级来启动进程

2.4.2 renice 可以调整正在执行中的进程的优先级

范例:使用方法

#查看优先级ni
[root@rocky01 ~]# ps axo pid,comm,ni

#nice
[root@rocky01 ~]# nice -n -10 ping 127.0.0.1
[root@rocky01 ~]# ps axo pid,cmd,nice |grep ping
  2118 ping 127.0.0.1              -10
  2120 grep --color=auto ping        0

#renice
[root@rocky01 ~]# renice -n -20 2118
2106 (process ID) old priority -10, new priority -20
[root@rocky01 ~]# ps axo pid,cmd,nice |grep ping
  2118 ping 127.0.0.1              -20
  2200 grep --color=auto ping        0

 

2.5 搜索进程

按条件搜索进程

  1. ps 选项 | grep " "
  2. pgrep 按预定义的模式
  3. /sbin/pidof 按确切的程序名称查看pid

2.5.1 pgrep

 格式:pgrep [options] pattern

 常用选项:

  • -u uid: effective user,生效者
  • -U uid: real user,真正发起运行命令者
  • -t terminal: 与指定终端相关的进程
  • -l: 显示进程名
  • -a: 显示完整格式的进程名
  • -P pid: 显示指定进程的子进程

范例:使用方法

[root@rocky01 ~]# pgrep -lu root

2.5.2 pidof

 格式:pidof [options] [program [...]]

 选项:-x 按脚本名称查找pid

范例:使用方法

[root@rocky01 ~]# pidof httpd
16761 16645 16644 16643 16642

[root@rocky01 ~]# cat ping.sh
#!/bin/bash
ping 127.0.0.1

#ping.sh必须有shebang机制,否则pidof -x 也无法查找到
[root@rocky01 ~]# pidof -x ping.sh 
19035

 

2.6 uptime 负载查询 

 /proc/uptime 包括两个值,单位 s

  • 第一个值表示:系统启动时长
  • 第二个值表示:空闲进程的总时长(按总的CPU核数计算)

uptime 和 w 显示以下内容

  • 当前时间
  • 系统已启动的时间
  • 当前上线人数
  • 系统平均负载(1、5、15分钟的平均负载,一般不会超过1,超过5时建议警报)

案例:系统平均负载

指在特定时间间隔内运行队列中的平均进程数,通常每个CPU内核的当前活动进程数不大于3,那么系统的性能良好。如果每个CPU内核的任务数大于5,那么此主机的性能有严重问题

如:linux主机是1个双核CPU,当Load Average 为6的时候说明机器已经被充分使用

[root@rocky01 ~]# uptime
 15:13:15 up  9:13,  1 user,  load average: 0.04, 0.02, 0.00
 
[root@rocky01 ~]# w
 15:14:30 up  9:14,  1 user,  load average: 0.06, 0.03, 0.00
...省略...

[root@rocky01 ~]# top
top - 15:14:41 up  9:14,  1 user,  load average: 0.05, 0.03, 0.00
...省略...

#load average:系统负载平均在过去的1、5和15分钟内忙不忙
#值一般超过5就会使系统变慢

 

2.7 mpstat 显示CPU相关统计 

来自于sysstat包

#间隔2秒执行3此
[root@rocky01 ~]# mpstat 2 3
Linux 4.18.0-372.9.1.el8.x86_64 (rocky01) 	09/02/2022 	_x86_64_	(2 CPU)

10:34:06 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
10:34:08 PM  all    0.00    0.00    0.25    0.00    0.25    0.25    0.00    0.00    0.00   99.25
10:34:10 PM  all    0.00    0.00    0.00    0.00    0.25    0.00    0.00    0.00    0.00   99.75
10:34:12 PM  all    0.00    0.00    0.25    0.00    0.00    0.00    0.00    0.00    0.00   99.75
Average:     all    0.00    0.00    0.17    0.00    0.17    0.08    0.00    0.00    0.00   99.58

 

2.8 top、htop 查看进程实时状态

2.8.1 top

常见选项

  • -d #指定刷新时间间隔,默认为3秒
  • -b #全部显示所有进程
  • -n #刷新多少次后退出
  • -H #线程模式

排序:

  • P:以占据的CPU百分比,%CPU
  • M:占据内存百分比,%MEM
  • T:累积占据CPU时长,TIME+

首部信息显示:

  • uptime信息:l命令
  • tasks及cpu信息:t命令
  • cpu分别显示:1 (数字)
  • memory信息:m命令

 

  • 退出命令:q
  • 修改刷新时间间隔:s
  • 终止指定进程:k
  • 保存文件:W

2.8.2 htop

 

2.9 free 内存空间

向/proc/sys/vm/drop_caches中写入相应的修改值,会清理缓存。建议先执行sync(sync 命令将所有未写的系统缓冲区写到磁盘中,包含已修改的 i-node、已延迟的块 I/O 和读写映射文件)。执行echo1、2、3 至 /proc/sys/vm/drop_caches, 达到不同的清理目的

 

如果因为是应用有像内存泄露、溢出的问题时,从swap的使用情况是可以比较快速可以判断的,但通过执行free 反而比较难查看。但核心并不会因为内存泄露等问题并没有快速清空buffer或cache(默认值是0),生产也不应该随便去改变此值。

 

一般情况下,应用在系统上稳定运行了,free值也会保持在一个稳定值的。当发生内存不足、应用获取不到可用内存、OOM错误等问题时,还是更应该去分析应用方面的原因,否则,清空buffer,强制腾出free的大小,可能只是把问题给暂时屏蔽了。

 

排除内存不足的情况外,除非是在软件开发阶段,需要临时清掉buffer,以判断应用的内存使用情况;或应用已经不再提供支持,即使应用对内存的时候确实有问题,而且无法避免的情况下,才考虑定时清空buffer。

 

常用选项

  • -b 以字节为单位
  • -m 以MB为单位
  • -g 以GB为单位
  • -h 易读格式
  • -o 不显示-/+buffers/cache行
  • -t   显示RAM + swap的总和
  • -s n 刷新间隔为n秒
  • -c n 刷新n次后即退出

范例:清理缓存

[root@rocky01 ~]# cat /proc/sys/vm/drop_caches
0
[root@rocky01 ~]# free -h
              total        used        free      shared  buff/cache   available
Mem:          3.6Gi       238Mi       3.0Gi       8.0Mi       399Mi       3.2Gi
Swap:         3.9Gi          0B       3.9Gi
[root@rocky01 ~]# echo 3 > /proc/sys/vm/drop_caches
[root@rocky01 ~]# free -h
              total        used        free      shared  buff/cache   available
Mem:          3.6Gi       221Mi       3.3Gi       8.0Mi       112Mi       3.2Gi
Swap:         3.9Gi          0B       3.9Gi

 

2.10 pmap 进程对应的内存映射

格式:pmap [options] pid [...]

选项:-x: 显示详细格式的信息

#使用方法1
[root@rocky01 ~]# pmap -x PID

#使用方法2
[root@rocky01 ~]# cat /proc/PID/maps

 

2.11 vmstat 虚拟内存信息 

格式:vmstat [options] [delay [count]]

[root@rocky01 ~]# 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    3415076   0   125060   0    0    45     9  112  181  0  1 99  0  0

procs
     r:可运行(正运行或等待运行)进程的个数,和核心数有关
     b:处于不可中断睡眠态的进程个数(被阻塞的队列的长度)
memory
     swpd: 交换内存的使用总量
     free:空闲物理内存总量
     buffer:用于buffer的内存总量
     cache:用于cache的内存总量
swap
     si:从磁盘交换进内存的数据速率(kb/s)
     so:从内存交换至磁盘的数据速率(kb/s)
io
     bi:从块设备读入数据到系统的速率(kb/s)
     bo: 保存数据至块设备的速率
system
     in: interrupts 中断速率,包括时钟
     cs: context switch     进程切换速率
cpu
     us:Time spent running non-kernel code
     sy: Time spent running kernel code
     id: Time spent idle. Linux 2.5.41前,包括IO-wait time.
     wa: Time spent waiting for IO.  2.5.41前,包括in idle.
     st: Time stolen from a virtual machine.  2.6.11前, unknown.

 

2.12 iostat 统计CPU和设备IO信息 

iostat 可以提供更丰富的IO性能状态数据

此工具由sysstat包提供

常用选项:

  • -c 只显示CPU行
  • -d 显示设备〈磁盘)使用状态
  • -k 以千字节为为单位显示输出
  • -t 在输出中包括时间戳
  • -x 在输出中包括扩展的磁盘指标
[root@rocky01 ~]# iostat
Linux 4.18.0-372.9.1.el8.x86_64 (rocky01) 	09/02/2022 	_x86_64_	(2 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.07    0.01    0.65    0.02    0.00   99.25

Device             tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
sda               3.18        79.02        15.72     365404      72707
scd0              0.03         0.37         0.00       1693          0
dm-0              2.58        67.25        14.83     310990      68574
dm-1              0.02         0.48         0.00       2220          0
dm-2              0.20         0.59         0.44       2749       2048


----------------------------------------------------------------------------
tps:该设备每秒的传输次数(Indicate the number of transfers per second that were issued to the device.)。
"一次传输"意思是"一次I/O请求"。多个逻辑请求可能会被合并为"一次I/O请求"。"一次传输"请求的大小是未知的。

kB_read/s:每秒从设备(drive expressed)读取的数据量;
kB_wrtn/s:每秒向设备(drive expressed)写入的数据量;
kB_read:读取的总数据量;
kB_wrtn:写入的总数量数据量;
这些单位都为Kilobytes。

 

2.13 iotop 监视磁盘I/O 

iotop命令是一个用来监视磁盘I/O使用状况的top类工具iotop具有与top相似的UI,其中包括PID、用户、I/O、进程等相关信息,可查看每个进程是如何使用IO

第一行:Read和Write速率总计

第二行:实际的Read和Write速率

第三行:参数如下:

  • 线程ID(按p切换为进程ID)
  • 优先级
  • 用户
  • 磁盘读速率
  • 磁盘写速率
  • swap交换百分比
  • IO等待所占的百分比

 

2.14 iftop 显示网络带宽使用情况 

 

2.15 nload 查看网络实时吞吐量 

nload 是一个实时监控网络流量和带宽使用情况,以数值和动态图展示进出的流量情况,通过EPEL源安装界面操作

  • 上下方向键、左右方向键、enter键或者tab键都就可以切换查看多个网卡的流量情况
  • 按 F2 显示选项窗口
  • 按 q 或者 Ctrl+C 退出 nload

 

2.16 nethogs 查看进程网络带宽的使用情况 

NetHogs是一个开源的命令行工具(类似于Linux的top命令),用来按进程或程序实时统计网络带宽使用率。

 

2.17 iptraf-ng 网络监视工具

 

2.18 dstat 系统资源统计 

dstat由pcp-system-tools包提供,但安装dstat包即可, 可用于代替 vmstat,iostat功能

格式:dstat [-afv] [options..] [delay [count]]

常用选项

  • -c 显示cpu相关信息
  • -C #,#,...,total
  • -d 显示disk相关信息
  • -D total,sda,sdb,...
  • -g 显示page相关统计数据
  • -m 显示memory相关统计数据
  • -n 显示network相关统计数据
  • -p 显示process相关统计数据
  • -r 显示io请求相关的统计数据
  • -s 显示swapped相关的统计数据
  • --tcp
  • --udp
  • --unix
  • --raw
  • --socket
  • --ipc
  • --top-cpu:显示最占用CPU的进程
  • --top-io: 显示最占用io的进程
  • --top-mem: 显示最占用内存的进程
  • --top-latency: 显示延迟最大的进程

 

2.19 glances 综合监控工具

此工具可以通过EPEL源安装,CentOS 8 目前已提供,但测试有问题

常用选项:

  • -b: 以Byte为单位显示网卡数据速率
  • -d: 关闭磁盘I/O模块
  • -f /path/to/somefile: 设定输入文件位置
  • -o {HTML|CSV}:输出格式
  • -m: 禁用mount模块
  • -n: 禁用网络模块
  • -t #: 延迟时间间隔
  • -1:每个CPU的相关数据单独显示

 

2.20 lsof 查看进程打开文件 

选项

  • -a:列出打开文件存在的进程
  • -c<进程名>:列出指定进程所打开的文件
  • -g:列出GID号进程详情
  • -d<文件号>:列出占用该文件号的进程
  • +d<目录>:列出目录下被打开的文件
  • +D<目录>:递归列出目录下被打开的文件
  • -n<目录>:列出使用NFS的文件
  • -i<条件>:列出符合条件的进程(4、6、协议、:端口、 @ip )
  • -p<进程号>:列出指定进程号所打开的文件
  • -u:列出UID号进程详情
  • -h:显示帮助信息
  • -v:显示版本信息。
  • -n: 不反向解析网络名字

范例:使用方法

#查看当前哪个进程正在使用此文件
[root@rocky01 ~]# lsof /var/log/messages
COMMAND PID USER   FD   TYPE DEVICE SIZE/OFF     NODE NAME
rsyslogd 915 root   5w   REG    8,2  1419936 134802547 /var/log/messages

#指定进程号,可以查看该进程打开的文件
[root@rocky01 ~]# lsof -p 9527

#查看指定程序打开的文件
[root@rocky01 ~]# lsof -c httpd

#查看指定用户打开的文件
lsof -u root | more

#查看所有网络连接,通过参数-i查看网络连接的情况,包括连接的ip、端口等以及一些服务的连接情况
#例如:sshd等。也可以通过指定ip查看该ip的网络连接情况
lsof -i –n      
lsof -i@127.0.0.1

范例:恢复正在使用中的误删除的文件

一、此文件必须要被打开
[root@rocky01 ~]# cat Willoneday.txt
echo "lsof test!"
[root@rocky01 ~]# tail -f Willoneday.txt &
[1] 18189

二、删除此文件
[root@rocky01 ~]# lsof Willoneday.txt
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF      NODE NAME
tail    18189 root    3r   REG  253,0       18 201392493 Willoneday.txt
[root@rocky01 ~]# rm -rf Willoneday.txt
[root@rocky01 ~]# cat Willoneday.txt
cat: Willoneday.txt: No such file or directory

三、找到此文件PID,进入fd(打开文件描述符),找到对应文件标识,重定向即可
[root@rocky01 ~]# lsof |grep delete
tail      18189                   root    3r      REG              253,0       18  201392493 /root/Willoneday.txt (deleted)
[root@rocky01 ~]# ll /proc/18189/fd/
total 0
lrwx------ 1 root root 64 Sep  3 01:11 0 -> /dev/pts/0
lrwx------ 1 root root 64 Sep  3 01:11 1 -> /dev/pts/0
lrwx------ 1 root root 64 Sep  3 01:11 2 -> /dev/pts/0
lr-x------ 1 root root 64 Sep  3 01:11 3 -> '/root/Willoneday.txt (deleted)'
lr-x------ 1 root root 64 Sep  3 01:11 4 -> anon_inode:inotify
[root@rocky01 ~]# cat /proc/18189/fd/3 > Willoneday.txt
[root@rocky01 ~]# cat Willoneday.txt
echo "lsof test!"

 

2.21 信号发送 

2.21.1 kill

kill:内部命令,可用来向进程发送控制信号,以实现对进程管理,每个信号对应一个数字,信号名称以SIG开头(可省略),不区分大小写

#显示当前系统可用信号:
[root@rocky01 ~]# kill -L
 1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL	 5) SIGTRAP
 6) SIGABRT	 7) SIGBUS	 8) SIGFPE	 9) SIGKILL	10) SIGUSR1
11) SIGSEGV	12) SIGUSR2	13) SIGPIPE	14) SIGALRM	15) SIGTERM
16) SIGSTKFLT	17) SIGCHLD	18) SIGCONT	19) SIGSTOP	20) SIGTSTP
21) SIGTTIN	22) SIGTTOU	23) SIGURG	24) SIGXCPU	25) SIGXFSZ
26) SIGVTALRM	27) SIGPROF	28) SIGWINCH	29) SIGIO	30) SIGPWR
31) SIGSYS	34) SIGRTMIN	35) SIGRTMIN+1	36) SIGRTMIN+2	37) SIGRTMIN+3
38) SIGRTMIN+4	39) SIGRTMIN+5	40) SIGRTMIN+6	41) SIGRTMIN+7	42) SIGRTMIN+8
43) SIGRTMIN+9	44) SIGRTMIN+10	45) SIGRTMIN+11	46) SIGRTMIN+12	47) SIGRTMIN+13
48) SIGRTMIN+14	49) SIGRTMIN+15	50) SIGRTMAX-14	51) SIGRTMAX-13	52) SIGRTMAX-12
53) SIGRTMAX-11	54) SIGRTMAX-10	55) SIGRTMAX-9	56) SIGRTMAX-8	57) SIGRTMAX-7
58) SIGRTMAX-6	59) SIGRTMAX-5	60) SIGRTMAX-4	61) SIGRTMAX-3	62) SIGRTMAX-2
63) SIGRTMAX-1	64) SIGRTMAX 

[root@rocky01 ~]# trap -l

常用信号

  • 1) SIGHUP 无须关闭进程而让其重读配置文件
  • 2) SIGINT 中止正在运行的进程;相当于Ctrl+c
  • 3) SIGQUIT 相当于ctrl+\
  • 9) SIGKILL 强制杀死正在运行的进程,可能会导致数据丢失,慎用!
  • 15) SIGTERM 终止正在运行的进程,默认信号
  • 18) SIGCONT 继续运行
  • 19) SIGSTOP 后台休眠

2.21.2 killall

killall命令用于杀死指定名字的进程

2.21.3 pkill

pkill命令可按模式杀死进程

范例:利用 0 信号实现进程的健康性检查

#如果信号为0,则不发送实际信号,但仍执行错误检查
[root@centos8 ~]#man kill
If signal is 0, then no actual signal is sent, but error checking is still performed.

[root@centos8 ~]#killall -0 ping
[root@centos8 ~]#echo $?
0
[root@centos8 ~]#killall -0 ping
ping: no process found
[root@centos8 ~]#echo $?
1

#此方式有局限性,即使进程处于停止或僵尸状态,此方式仍然认为是进程是健康的

 

2.22 cockpit  CentOS8新特性 

由cockpit包提供,当前Ubuntu和CentOS7也支持此工具

Cockpit 是CentOS 8 取入的新特性,是一个基于 Web 界面的应用,它提供了对系统的图形化管理

  • 监控系统活动(CPU、内存、磁盘 IO 和网络流量)
  • 查看系统日志条目
  • 查看磁盘分区的容量
  • 查看网络活动(发送和接收)
  • 查看用户帐户
  • 检查系统服务的状态
  • 提取已安装应用的信息
  • 查看和安装可用更新(如果以 root 身份登录)并在需要时重新启动系统
  • 打开并使用终端窗口

 

2.23 作业管理

Linux的作业控制

前台作业:通过终端启动,且启动后一直占据终端

后台作业:可通过终端启动,但启动后即转入后台运行(释放终端)

2.23.1让作业运行于后台

运行中的作业: Ctrl+z
尚未启动的作业: COMMAND &

后台作业虽然被送往后台运行,但其依然与终端相关;

退出终端,将关闭后台作业。如果希望送往后台后,剥离与终端的关系

[root@rocky01 ~]# nohup COMMAND &>/dev/null & 
[root@rocky01 ~]# screen;COMMAND
[root@rocky01 ~]# tmux;COMMAND

2.23.2 查看当前终端所有作业

[root@rocky01 ~]# jobs

2.23.3 作业控制

fg [[%]JOB_NUM]:把指定的后台作业调回前台
bg [[%]JOB_NUM]:让送往后台的作业在后台继续运行
kill [%JOB_NUM]: 终止指定的作业

范例:nohup

[root@rocky01 ~]# nohup ping 127.0.0.1 &> /dev/null &
[1] 20691
[root@rocky01 ~]# pstree -p |grep ping
           |-sshd(942)-+-sshd(19392)---sshd(19394)---bash(19395)---ping(20691)

#关闭对应的终端,再观察进程的父进程
[root@rocky01 ~]# pstree -p |grep ping
           |-ping(20691)

 

2.24 并行运行

利用后台执行,实现并行功能,即同时运行多个进程,提高效率

后台执行的程序要想退出要个wait指令否则,它什么时候退出,敲回车才能看出来

方法1

[root@rocky01 ~]# cat all.sh
/root/f1.sh&
/root/f2.sh&
/root/f3.sh&
wait

方法2

(/root/f1.sh&);(/root/f2.sh&);(/root/f3.sh&)

方法3

[root@rocky01 ~]# /root/f1.sh&/root/f2.sh&/root/f3.sh&wait

范例:多组命令实现并行

[root@rocky01 ~]# { ping -c3 127.1; ping 127.2; }& { ping -c3 127.3 ;ping 127.4; }&

范例:扫描主机

[root@centos8 ~]#cat scan_host.sh
#!/bin/bash

#******************************************************
# Author:          会不会有那么一天
# QQ:              791270697
# Date:            2022-09-04
# FileName:        2.sh
# Version:         1.0.0
# Description:     The test script
# BLOG:            https://www.cnblogs.com/Willoneday
#******************************************************

net=10.0.0
for i in {1..254};do
   { 
    if ping -c1 -W1 $net.$i &> /dev/null;then
        echo $net.$i is up
    else
        echo $net.$i is down
    fi
   }&
done
wait

[root@rocky01 ~]# bash scanhost.sh
10.0.0.7 is up
10.0.0.1 is up
10.0.0.2 is up
10.0.0.6 is up
10.0.0.8 is up
10.0.0.3 is down
10.0.0.5 is down
10.0.0.29 is down
10.0.0.14 is down
10.0.0.15 is down
10.0.0.10 is down
10.0.0.23 is down
10.0.0.12 is down
......
10.0.0.245 is down
10.0.0.246 is down
10.0.0.240 is down
[root@rocky01 ~]#

 


3 任务计划

通过任务计划,可以让系统自动的按时间或周期性任务执行任务

注意: 此功能需要实现邮件通知,必须安装并启动邮件服务

范例: 环境准备

[root@rocky01 ~]# yum -y install postfix
[root@rocky01 ~]# systemctl enable --now postfix

未来的某时间点执行一次任务

  • at 指定时间点,执行一次性任务
  • batch 系统自行选择空闲时间去执行此处指定的任务

周期性运行某任务

  • cron

3.1 一次性任务

3.1.1 at 工具

由包 at 提供

  • 依赖与atd服务,需要启动才能实现at任务
  • at队列存放在/var/spool/at目录中,ubuntu存放在/var/spool/cron/atjobs目录下
  • 执行任务时PATH变量的值和当前定义任务的用户身份一致

格式:at [option] TIME

常用选项:

  • -V 显示版本信息
  • -t time   时间格式 [[CC]YY]MMDDhhmm[.ss]
  • -l 列出指定队列中等待运行的作业;相当于atq
  • -d N 删除指定的N号作业;相当于atrm
  • -c N 查看具体作业N号任务
  • -f file 指定的文件中读取任务
  • -m 当任务被完成之后,将给用户发送邮件,即使没有标准输出

注意:

作业执行命令的结果中的标准输出和错误以执行任务的用户身份发邮件通知给 root

默认CentOS 8 最小化安装没有安装邮件服务,需要自行安装

TIME:定义出什么时候进行 at 这项任务的时间

HH:MM [YYYY-mm-dd]
noon, midnight, teatime(4pm),tomorrow
now+#{minutes,hours,days, OR weeks}
范例:at 时间格式
#规定在某年某月的某一天的特殊时刻进行该项任务
HH:MM YYYY-MM-DD   
02:00 1949-10-01   

HH:MM[am|pm] [Month] [Date]
06pm March 17
17:20 tomorrow

#在某个时间点再加几个时间后才进行该项任务
HH:MM[am|pm] + number [minutes|hours|days|weeks]
now + 5 min 
02pm + 3 days

at 任务执行方式:

  • 交互式
  • 输入重定向
  • at -f file

/etc/at.{allow,deny} 控制用户是否能执行at任务

  • 白名单:/etc/at.allow 默认不存在,只有该文件中的用户才能执行at命令
  • 黑名单:/etc/at.deny 默认存在,拒绝该文件中用户执行at命令,而没有在at.deny 文件中的使用者则可执行
  • 如果两个文件都不存在,只有 root 可以执行 at 命令

 

3.2 cron 周期性任务计划 

周期性任务计划cron相关的程序包:

  • cronie:主程序包,提供crond守护进程及相关辅助工具
  • crontabs:包含CentOS提供系统维护任务
  • cronie-anacron:cronie的补充程序,用于监控cronie任务执行状况,如:cronie中的任务在过去该运行的时间点未能正常运行,则anacron会随后启动一次此任务

cron 依赖于crond服务,确保crond守护处于运行状态

cron任务分为:

  • 系统cron任务:系统维护作业,/etc/crontab 主配置文件, /etc/cron.d/ 子配置文件
  • 用户cron任务:
    • 红帽系统保存在 /var/spool/cron/USERNAME
    • Ubuntu 系统存放在/var/spool/cron/crontabs/USERNAME,利用 crontab 命令管理

计划任务日志:/var/log/cron

3.2.1 系统cron计划任务

/etc/crontab 格式说明,详情参见 man 5 crontab

[root@rocky01 ~]# cat /etc/crontab
SHELL=/bin/bash                      #默认的SHELL类型
PATH=/sbin:/bin:/usr/sbin:/usr/bin   #默认的PATH变量值,可修改为其它路径
MAILTO=root                          #默认标准输出和错误发邮件给root,可以指向其它用户

# For details see man 4 crontabs

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed
# 分 时 天 月 周 用户 命令

                     
范例:使用方法 
#晚上9点10分运行echo命令,输出信息仍会发送到root 邮箱
10 21 * * * zhangsan /bin/echo "Howdy!"

#每3小时echo和wall命令
0 */3 * * * zhangsan /bin/echo “howdy”;wall “Willoneday!”
crond任务相关文件
/etc/crontab 配置文件
/etc/cron.d/ 配置文件
/etc/cron.hourly/ 脚本
/etc/cron.daily/ 脚本
/etc/cron.weekly/ 脚本
/etc/cron.monthly/ 脚本

3.2.2 用户计划任务

crontab命令

  • 每个用户都有专用的cron任务文件:/var/spool/cron/USERNAME
  • 默认标准输出和错误会被发邮件给对应的用户,如:root创建的任务就发送至root的邮箱
  • root能够修改其它用户的作业
  • 用户的cron 中默认 PATH=/usr/bin:/bin,如果使用其它路径,在任务文件的第一行加PATH=/path或者加入到计划任务执行的脚本中
  • 第六个字段指定要运行的命令。 该行的整个命令部分,直至换行符或“%”字符,指定的shell执行.除非使用反斜杠(\)进行转义,否则该命令中的“%”字符将变为换行符,并且第一个%之后的所有数据将作为标准输入发送到该命令。

 crontab命令格式:

 crontab [-u user] [-l | -r | -e] [-i]

 常用选项:

  • -l 列出所有任务
  • -e 编辑任务
  • -r 移除所有任务
  • -i 同-r一同使用,以交互式模式移除指定任务
  • -u user 指定用户管理cron任务,仅root可运行

控制用户执行计划任务:

  • /etc/cron.{allow,deny}
范例:Ubuntu修改默认文本编辑器为vim
[root@ubuntu01 ~]# cat /etc/profile.d/env.sh
export EDITOR=vim
[root@ubuntu01 ~]# source /etc/profile.d/env.sh
范例:PATH变量
#方法1:在计划任务配置中指定PATH
[root@rocky01 ~]# crontab -l
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
* * * * * useradd hehe;echo $PATH

#方法2:在脚本中指定PATH变量
[root@rocky01 ~]# crontab -l
* * * * * /data/test.sh
[root@rocky01 ~]# cat /data/test.sh
#!/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
useradd hehe
echo $PATH
面试题:11月每天的6-12点之间每隔2小时执行/app/bin/test.sh
[root@rocky01 ~]# crontab -l
0 6-12/2 * 11 * /app/bin/test.sh
注意:运行结果的标准输出和错误以邮件通知给相关用户
(1) COMMAND > /dev/null 
(2) COMMAND &> /dev/null

cron任务中不建议使用%,它有特殊用途,它表示换行的特殊意义,且第一个%后的所有字符串会被将成当作命令的标准输入,如果在命令中要使用%,则需要用 \ 转义

注意:将%放置于单引号中是不支持的

范例: 在crontab中%的用法
30 2 * * * /bin/cp -a /etc/ /data/etc`date +\%F_\%T`
30 2 * * * /bin/cp -a /etc/ /data/etc`date +‘%F_%T’` #有问题
范例:秒级别运行任务
for min in 0 1 2; do echo "hi"; sleep 20; done

 


二、系统启动和内核管理

1 CentOS 6 的启动管理

1.1 CentOS 6 启动流程

  1. 加载BIOS的硬件信息,获取第一个启动设备
  2. 读取第一个启动设备MBR的引导加载程序(grub)的启动信息
  3. 加载核心操作系统的核心信息,核心开始解压缩,并尝试驱动所有的硬件设备
  4. 核心执行init程序,并获取默认的运行信息
  5. init程序执行/etc/rc.d/rc.sysinit文件,重新挂载根文件系统
  6. 启动核心的外挂模块
  7. init执行运行的各个批处理文件(scripts)
  8. init执行/etc/rc.d/rc.local
  9. 执行/bin/login程序,等待用户登录
  10. 登录之后开始以Shell控制主机

(1)硬件启动 POST

POST:Power-On-Self-Test,加电自检,是BIOS功能的一个主要部分。负责完成对CPU、主板、内存、硬盘子系统、显示子系统、串并行接口、键盘等硬件情况的检测

主板的ROM:BIOS,Basic Input and Output System,保存着有关计算机系统最重要的基本输入输出程序,系统信息设置、开机加电自检程序和系统启动自举程序等

主板的RAM:CMOS互补金属氧化物半导体,保存各项参数的设定,按次序查找引导设备,第一个有引导程序的设备为本次启动设备

 

(2)启动加载器 bootloader

(2.1)grub 功能和组成

bootloader: 引导加载器,引导程序

  • Windows: ntloader,仅是启动OS
  • Linux:功能丰富,提供菜单,允许用户选择要启动系统或不同的内核版本;把用户选定的内核装载到内存中的特定空间中,解压、展开,并把系统控制权移交给内核

Linux的bootloader

  • LILO:LInux LOader,早期的bootloader,功能单一
  • GRUB: GRand Unified Bootloader, CentOS 5,6 GRUB 0.97: GRUB Legacy, CentOS 7 以后使用GRUB 2.02

GRUB 启动阶段

primary boot loader :

  • 1st stage:MBR的前446个字节
  • 1.5 stage:MBR 之后的扇区,让stage1中的bootloader能识别stage2所在的分区上的文件系统

secondary boot loader :

  • 2nd stage,分区文件/boot/grub/
(2.2)CentOS6 grub安装

安装 grub的两种方法:

(1)grub-install 安装grub stage1和stage1_5到/dev/DISK磁盘上,并复制GRUB相关文件到 DIR/boot目录下

grub-install  /dev/DISK

(2)grub命令

#grub
grub> root (hd#,#)
grub> setup (hd#)
实战范例:grub的第1阶段故障无法启动,进行修复
#模拟破坏grub第1阶段
[root@centos6 grub]#dd if=/dev/zero of=/dev/sda bs=1 count=446

#光盘启动,进入rescue模式
#chroot /mnt/sysimage
#grub-install /dev/sda
#sync
#exit
#exit
#reboot
范例:centos6下的/boot/grub/grub.conf配置文件
[root@centos6 ~]# cat /boot/grub/grub.conf
default=0
timeout=5
title Willoneday
root (hd0,0)
kernel /vmlinuz-2.6.32-754.e16.x86_64 root=/dev/sda2
initrd /initramfs-2.6.32-754.e16.x86_64.img

###解读###
#default:设定默认启动的菜单项;落单项(title)编号从0开始
#timeout:指定菜单项等待选项选择的时长
#kernel XXX:设定本次启动的内核文件;额外还可添加许多内核支持使用的cmdline参数;例如:max_loop=100 selinux=0
#hd表示硬盘,第一个0表示第一个硬盘,第二个0代表第一个分区
#root=/dev/sda2 真正硬盘的根分区
#initrd XXX:设定为选定的内核提供额外文件的ramdisk
范例: 破解root口令
(1) 编辑grub菜单(选定要编辑的title,而后使用a 或 e 命令)
(2) 在选定的kernel后附加1, s, S,single 都可以进入单用户模式
(3) 在kernel所在行,键入“b”命令

 

(3)加载 kernel

范例:误删除/boot/initramfs-2.6.32-754.el6.x86_64.img无法启动,故障恢复
[root@centos6 ~]#rm -f /boot/initramfs-2.6.32-754.el6.x86_64.img
[root@centos6 ~]#reboot
#进入rescue模式
#chroot /mnt/sysimage
#mkinitrd /boot/initramfs-$(uname -r).img $(uname -r)
#sync
#exit
#exit
#reboot

 

(4)init初始化

(4.1)运行级别

运行级别:为系统运行或维护等目的而设定;0-6:7个级别,一般使用3, 5做为默认级别

0:关机
1:单用户模式(root自动登录), single, 维护模式
2:多用户模式,启动网络功能,但不会启动NFS;维护模式
3:多用户模式,正常模式;文本界面
4:预留级别;可同3级别
5:多用户模式,正常模式;图形界面
6:重启
#切换级别:
init #

#查看级别:
runlevel 
who -r
(4.2)初始化脚本 sysinit
/etc/rc.d/rc.sysinit
系统初始化脚本功能
(1) 设置主机名
(2) 设置欢迎信息
(3) 激活udev和selinux 
(4) 挂载/etc/fstab文件中定义的文件系统
(5) 检测根文件系统,并以读写方式重新挂载根文件系统
(6) 设置系统时钟
(7) 激活swap设备
(8) 根据/etc/sysctl.conf文件设置内核参数
(9) 激活lvm及software raid设备
(10)加载额外设备的驱动程序
(11)清理操作

 

(5)Centos6服务管理

#查看服务在所有级别的启动或关闭设定情形:
chkconfig [--list] [name]
范例:自定义服务脚本
[root@centos6 ~]# cat /etc/init.d/testsrv 
#!/bin/bash
# chkconfig: - 96 3
# description: This is test service script
. /etc/init.d/functions 
start(){
   [ -e /var/lock/subsys/testsrv ] && exit || touch /var/lock/subsys/testsrv
   action "Starting testsrv"
    sleep 2 }
stop(){
   [ -e   /var/lock/subsys/testsrv ] && rm /var/lock/subsys/testsrv || exit
   action "Stopping testsrv"
}
status(){
   [ -e /var/lock/subsys/testsrv ] && echo "testsrv is running..." || echo
"testsrv is stopped"
}
case $1 in
start)
    start
   ;;
stop)
    stop
   ;;
restart)
    stop
    start
   ;;
status)
   status
   ;;
*)
    echo $"Usage: $0 {start|stop|status|restart}"
    exit 2
esac
[root@centos6 ~]# chkconfig --add testsrv
[root@centos6 ~]# chkconfig --list testsrv
testsrv       0:off 1:off 2:off 3:off 4:off 5:off 6:off
[root@centos6 ~]# chmod +x /etc/init.d/testsrv
[root@centos6 ~]# service testsrv start
/sbin:/usr/sbin:/bin:/usr/bin
Starting testsrv                                           [ OK ]
[root@centos6 ~]# chkconfig --del testsrv

 

(6)非独立服务

服务分为独立服务和非独立服务

瞬态(Transient)服务被超级守护进程 xinetd 进程所管理,也称为非独立服务

进入的请求首先被xinetd代理

配置文件:

/etc/xinetd.conf
/etc/xinetd.d/<service>
范例:Centos6 开启 telnet服务
[root@centos6 ~]# yum -y install telnet-server
#设为开机启动
[root@centos6 ~]# chkconfig telnet on   
[root@centos6 ~]# service xinetd start

#注:由xinetd控制telnet的启动

 

(7)开机启动文件 rc.local

/etc/rc.local
/etc/rc.d/rc.local

注意:正常级别下,最后启动一个服务S99local没有链接至/etc/rc.d/init.d一个服务脚本,而是指向了/etc/rc.d/rc.local脚本

不便或不需写为服务脚本放置于/etc/rc.d/init.d/目录,且又想开机时自动运行的命令,可直接放置于/etc/rc.d/rc.local文件中

/etc/rc.d/rc.local在指定运行级别脚本后运行

注意: 默认Ubuntu /etc/rc.local 文件,可以创建此脚本文件并添加执行权限,rc.local的首行必须有 shebang机制

 

(8)Centos6 启动过程总结

POST--
GRUB1阶段MBR446--
GRUB1.5MBR之后的空间(提供grub2文件所有分区的文件系统)--
GRUB2阶段(grub.conf)
--kernel(initramfs.img)--根分区--
/sbin/init--/etc/inittab--/etc/rc.sysinit(系统初始化脚本)--
/etc/rc.d/rc--/etc/rcN.d/K,S(/etc/init.d/)--/etc/rc.local--login登录

 


2 systemd和启动流程

2.1 systemd 特性

Systemd:从 CentOS 7 版本之后开始用 systemd 实现init进程,系统启动和服务器守护进程管理器,负责在系统启动或运行时,激活系统资源,服务器进程和其它进程

systemd 核心概念:unit

unit表示不同类型的systemd对象,通过配置文件进行标识和配置;文件中主要包含了系统服务、监听socket、保存的系统快照以及其它与init相关的信息

Unit类型:

#查看unit类型
[root@rocky01 ~]# systemctl -t help
Available unit types:
service
socket
target
device
mount
automount
swap
timer
path
slice
scope
  • service unit: 文件扩展名为.service, 用于定义系统服务
  • Socket unit: .socket, 定义进程间通信用的socket文件,也可在系统启动时,延迟启动服务,实现按需启动
  • Target unit: 文件扩展名为.target,用于模拟实现运行级别
  • Device unit: .device, 用于定义内核识别的设备
  • Mount unit: .mount, 定义文件系统挂载点
  • Snapshot unit: .snapshot, 管理系统快照
  • Swap unit: .swap, 用于标识swap设备
  • Automount unit: .automount,文件系统的自动挂载点
  • Path unit: .path,用于定义文件系统中的一个文件或目录使用,常用于当文件系统变化时,延迟激活服务,如:spool 目录

 

unit的配置文件

/usr/lib/systemd/system #每个服务最主要的启动脚本设置,类似于之前的/etc/init.d/

/lib/systemd/system #ubutun的对应目录,兼容于CentOS7,8和Ubuntu

 

/run/systemd/system #系统执行过程中所产生的服务脚本,比上面目录优先运行

/etc/systemd/system #管理员建立的执行脚本,类似于/etc/rcN.d/Sxx的功能,比上面目录优先运行

 

2.2 systemctl管理系统服务service unit

命令:systemctl COMMAND name.service

#启动:相当于service name start 
systemctl start name.service   

#停止:相当于service name stop
systemctl stop name.service

#重启:相当于service name restart 
systemctl restart name.service 

#查看状态:相当于service name status
systemctl status name.service

#重新加载配置
systemctl reload sshd.service

#禁止自动和手动启动:
systemctl mask name.service

#取消禁止
systemctl unmask name.service

#查看某服务当前激活与否的状态:
systemctl is-active name.service

#查看service文件内容
systemctl cat sshd

#查看所有已经激活的服务:
systemctl list-units --type service 或
systemctl list-units -t service

#查看所有服务:
systemctl list-units --type service --all 或
systemctl list-units --type service -a

#设定某服务开机自启,相当于chkconfig name on
systemctl enable name.service 

#设定某服务开机禁止启动:相当于chkconfig name off
systemctl disable name.service

#查看所有服务的开机自启状态,相当于chkconfig --list
systemctl list-unit-files --type service

#用来列出该服务在哪些运行级别下启用和禁用:chkconfig –list name
ls /etc/systemd/system/*.wants/name.service

#查看服务是否开机自启:
systemctl is-enabled name.service

#列出失败的服务
systemctl --failed --type=service
 
#开机并立即启动或停止
systemctl enable --now postfix 
systemctl disable  --now postfix

#查看服务的依赖关系:
systemctl list-dependencies name.service

#杀掉进程:
systemctl kill unitname

 

2.3 service unit文件格式

/etc/systemd/system:系统管理员和用户使用

/usr/lib/systemd/system:发行版打包者使用

unit 格式说明:

  • 以 “#” 开头的行后面的内容会被认为是注释
  • 相关布尔值,1、yes、on、true 都是开启,0、no、off、false 都是关闭
  • 时间单位默认是秒,所以要用毫秒(ms)分钟(m)等须显式说明

service unit file文件通常由三部分组成:

  • Type:定义影响ExecStart及相关参数的功能的unit进程启动类型
    • simple:默认值,这个daemon主要由ExecStart接的指令串来启动,启动后常驻于内存中
    • forking:由ExecStart启动的程序透过spawns延伸出其他子程序来作为此daemon的主要服务。原生父程序在启动结束后就会终止
    • oneshot:与simple类似,不过这个程序在工作完毕后就结束了,不会常驻在内存中
    • dbus:与simple类似,但这个daemon必须要在取得一个D-Bus的名称后,才会继续运作.因此通常也要同时设定BusNname= 才行
    • notify:在启动完成后会发送一个通知消息。还需要配合 NotifyAccess 来让 Systemd 接收消息
    • idle:与simple类似,要执行这个daemon必须要所有的工作都顺利执行完毕后才会执行。这类的daemon通常是开机到最后才执行即可的服务
  • [Unit]:定义与Unit类型无关的通用选项;用于提供unit的描述信息、unit行为及依赖关系等
  • [Service]:与特定类型相关的专用选项;此处为Service类型
  • [Install]:定义由“systemctl enable”以及"systemctl disable“命令在实现服务启用或禁用时用到的一些选项

Unit段的常用选项:

  • Description:描述信息
  • After:定义unit的启动次序,表示当前unit应该晚于哪些unit启动,其功能与Before相反
  • Requires:依赖到的其它units,强依赖,被依赖的units无法激活时,当前unit也无法激活
  • Wants:依赖到的其它units,弱依赖
  • Conflicts:定义units间的冲突关系

Service段的常用选项:

  • EnvironmentFile:环境配置文件
  • ExecStart:指明启动unit要运行命令或脚本的绝对路径
  • ExecStartPre: ExecStart前运行
  • ExecStartPost: ExecStart后运行
  • ExecStop:指明停止unit要运行的命令或脚本
  • Restart:当设定Restart=1 时,则当次daemon服务意外终止后,会再次自动启动此服务

Install段的常用选项:

  • Alias:别名,可使用systemctl command Alias.service
  • RequiredBy:被哪些units所依赖,强依赖
  • WantedBy:被哪些units所依赖,弱依赖
  • Also:安装本服务的时候还要安装别的相关服务

注意:对于新创建的unit文件,或者修改了的unit文件,要通知systemd重载此配置文件,而后可以选择重启

[root@rocky01 ~]# systemctl daemon-reload
[root@rocky01 ~]# systemctl cat sshd.service
# /usr/lib/systemd/system/sshd.service
[Unit]
Description=OpenSSH server daemon
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target sshd-keygen.target
Wants=sshd-keygen.target

[Service]
Type=notify
EnvironmentFile=-/etc/crypto-policies/back-ends/opensshserver.config
EnvironmentFile=-/etc/sysconfig/sshd
ExecStart=/usr/sbin/sshd -D $OPTIONS $CRYPTO_POLICY
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=42s

[Install]
WantedBy=multi-user.target

范例:自定义service的unit文件

[root@rocky01 ~]# cat /lib/systemd/system/hello.service
[Unit]
Description=Hello World
[Service]
TimeoutStartSec=0
ExecStart=/bin/sh -c "while true; do echo Hello World; sleep 1; done"
ExecStop=/bin/kill sh
[Install]
WantedBy=multi-user.target
[root@rocky01 ~]#
[root@rocky01 ~]# systemctl start hello
[root@rocky01 ~]# systemctl status hello
● hello.service - Hello World
   Loaded: loaded (/usr/lib/systemd/system/hello.service; disabled; vendor preset: disabled)
   Active: active (running) since Fri 2022-10-07 22:07:03 CST; 3s ago
 Main PID: 2174 (sh)
    Tasks: 2 (limit: 23457)
   Memory: 600.0K
   CGroup: /system.slice/hello.service
           ├─2174 /bin/sh -c while true; do echo Hello World; sleep 1; done
           └─2178 sleep 1

Oct 07 22:07:03 rocky01 systemd[1]: Started Hello World.
Oct 07 22:07:03 rocky01 sh[2174]: Hello World
Oct 07 22:07:04 rocky01 sh[2174]: Hello World
Oct 07 22:07:05 rocky01 sh[2174]: Hello World
Oct 07 22:07:06 rocky01 sh[2174]: Hello World

范例:服务unit文件解读

[Unit]
Description=The Nginx HTTP Server daemon # 描述信息
After=network.target remote-fs.target nss-lookup.target # 指定启动nginx之前需要其他的其他服务,如network.target等

[Service]
# Type为服务类型,仅启动一个主进程的服务为simple,需要启动若干子进程的服务为forking
Type=forking 
# 设置执行systemctl start nginx后需要启动的具体命令
ExecStart=/usr/local/nginx/sbin/nginx
# 设置执行systemctl reload nginx后需要执行的具体命令
ExecReload=/usr/local/nginx/sbin/nginx -s reload
# 设置执行systemctl stop nginx后需要执行的具体命令
ExecStop=/bin/kill -s QUIT ${MAINPID}

[Install]
# 设置在什么模式下被安装,设置开机启动的时候需要
WantedBy=multi-user.target

范例:Ubuntu实现开机自动运行程序

[root@ubuntu1804 ~]# cat /etc/rc.local
#!/bin/bash
echo -e '\E[31;1mstarting test service\E[0m'
sleep 10
[root@ubuntu1804 ~]# chmod +x /etc/rc.local
[root@ubuntu1804 ~]# reboot

 

2.4 运行级别

target units:相当于CentOS 6之前的runlevel ,unit配置文件:.target

ls /usr/lib/systemd/system/*.target
systemctl list-unit-files --type target  --all

和运行级别对应关系

0  ==> runlevel0.target, poweroff.target

1  ==> runlevel1.target, rescue.target

2  ==> runlevel2.target, multi-user.target

3  ==> runlevel3.target, multi-user.target

4  ==> runlevel4.target, multi-user.target

5  ==> runlevel5.target, graphical.target

6  ==> runlevel6.target, reboot.target

获取默认运行级别

相当于查看 /etc/inittab

[root@rocky01 ~]# systemctl get-default

修改默认级别

相当于修改 /etc/inittab

[root@rocky01 ~]# systemctl set-default name.target

范例:禁用ctrl+alt+delete 重启快捷键

[root@rocky01 ~]# systemctl mask -f ctrl-alt-del.target
Removed /etc/systemd/system/ctrl-alt-del.target.
Created symlink /etc/systemd/system/ctrl-alt-del.target → /dev/null.

#下面两个功能相同:重新加载配置
[root@rocky01 ~]# init q 
[root@rocky01 ~]# systemctl daemon-reload

#注:不加-f参数可能会失败

 

2.5 设置内核参数

设置内核参数,只影响当次启动

启动时,到启动菜单,按e键,找到在linux 开头的行后添加systemd.unit=desired.target

比如:

#进入runlevel 3
systemd.unit=multi-user.target

 

2.6 CentOS 7之后版本引导顺序

1. UEFi或BIOS初始化,运行POST开机自检
2. 选择启动设备
3. 引导装载程序, centos7是grub2,加载装载程序的配置文件:
  /etc/grub.d/
  /etc/default/grub 
  /boot/grub2/grub.cfg
4. 加载initramfs驱动模块
5. 加载内核选项
6. 内核初始化,centos7使用systemd代替init 
7. 执行initrd.target所有单元,包括挂载/etc/fstab
8. 从initramfs根文件系统切换到磁盘根目录
9. systemd执行默认target配置,配置文件/etc/systemd/system/default.target
10. systemd执行sysinit.target初始化系统及basic.target准备操作系统
11. systemd启动multi-user.target下的本机与服务器服务
12. systemd执行multi-user.target下的/etc/rc.d/rc.local
13. Systemd执行multi-user.target下的getty.target及登录服务
14. systemd执行graphical需要的服务

范例:启动详细过程网页版

[root@rocky01 ~]# systemd-analyze plot > boot.html

 

2.7 破解 CentOS 7和8的 root 密码

方法一

启动时任意键暂停启动
按e键进入编辑模式
将光标移动linux 开始的行,添加内核参数 rd.break
按ctrl-x启动
mount –o remount,rw /sysroot
chroot /sysroot
passwd root
#如果SELinux是启用的,才需要执行下面操作,如查没有启动,不需要执行
touch /.autorelabel
exit
reboot

方法二 

#此方式也适用于ubuntu18.04
启动时任意键暂停启动
按e键进入编辑模式
将光标移动linux 开始的行,改为 rw init=/sysroot/bin/sh
按ctrl-x启动
chroot /sysroot
passwd root
#如果SELinux是启用的,才需要执行下面操作,如查没有启动,不需要执行
touch /.autorelabel
exit
reboot

 

2.8 实现 GRUB2 安全

#添加grub密码
[root@rocky01 ~]# grub2-setpassword 
Enter password: 
Confirm password: 
[root@rocky01 ~]# cat /boot/grub2/user.cfg
GRUB2_PASSWORD=grub.pbkdf2.sha512.10000.60AAA29A65F4DC77E8861EF25BDE2034C9B30CE1
E07EE688D7F30460E7E87E7356B0893A6DFFB250B27D2EB9D3ED3E9207199C494D7882E2E8C772C8
2E2DDB7A.5E42FD69FA04293DECD68F077E83875A8E4572A7FBB89BA9F161B15EAFE54FBA963FE5D
52E16764944823396231803E5118DA1D9CAF3EB73C175A7D7A3682A90

#清空grub密码
[root@centos8 ~]#cat /dev/null > /boot/grub2/user.cfg 
#或者
[root@centos8 ~]#rm -f /boot/grub2/user.cfg

 

2.9 故障排错实战案例

实战案例1:CentOS 7,8 破坏MBR后进行恢复

dd if=/dev/zero of=/dev/sda bs=1 count=446
光盘进入救援模式
grub2-install --root-directory=/mnt/sysimage /dev/sda

实战案例2:CentOS 7,8 删除 /boot/grub2/ 所有内容进行恢复

 

#光盘进入救援模式
chroot /mnt/sysimage
grub2-install /dev/sda
grub2-mkconfig -o /boot/grub2/grub.cfg

实战案例3:CentOS 7,8 删除 /boot/ 下所有文件后进行恢复

#模拟删除/boot/下所有文件
[root@rocky01 ~]#rm -rf /boot/*

#1.光盘救援模式下安装grub2
#特别说明:Centos8 必须先修复grub,再安装kernel,否则安装kernel-core时会提示grub出错
#centos8
chroot /mnt/sysroot
#centos7
chroot /mnt/sysimage
#安装grub
grub2-install /dev/sda  #BIOS环境
grub2-install            #UEFI环境

#2.安装Kernel
#CentOS 7 
mount /dev/sr0 /mnt
rpm –ivh /mnt/Packages/kernel-3.10.0-1062.el7.x86_64.rpm --force
#CentOS 8 
mount /dev/sr0 /mnt
rpm -ivh /mnt/BaseOS/Packages/kernel-core-4.18.0-147.el8.x86_64.rpm --force

#3.修复grub配置文件
#生成grub.cfg文件
grub2-mkconfig –o /boot/grub2/grub.cfg

#4.退出重启
sync
sync
exit
exit

 

3 /proc 目录和内核参数管理

/proc目录:内核把自己内部状态信息及统计信息,以及可配置参数通过proc伪文件系统加以输出

sysctl是一个允许改变正在运行中的Linux系统的接口,修改的是针对整个系统的内核参数。sysctl的修改是立即且临时的(重启后失效)。也可以通过修改sysctl.conf配置文件,达到永久生效。

常用内核参数:

  • net.ipv4.ip_forward
  • net.ipv4.icmp_echo_ignore_all  #禁止ping通本主机
  • net.ipv4.ip_nonlocal_bind   #允许应用程序可以监听本地不存在的IP
  • fs.file-max = 1020000           #全局打开文件的最大数

 

  • vm.overcommit_memory = 0  
    • #0表示内核将检查是否有足够可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则内存申请失败,并把错误返回给应用进程。
    • #1表示内核允许分配所有的物理内存,而不管当前的内存状态如何。
    • #2表示内核允许分配超过所有物理内存和交换空间总和的内存。

 

vm.swappiness = 10           #设置内存还剩余10%空闲空间时,就会使用swap空间,默认值为30,值越大表示越倾向于使用swap

 

#禁用IPv6

  • net.ipv6.conf.all.disable_ipv6 = 1
  • net.ipv6.conf.default.disable_ipv6 = 1

3.1 sysctl 将值写入变量

sysctl -w path.to.parameter=VALUE

3.2 默认配置文件

/etc/sysctl.conf

范例:临时设置某参数

sysctl -w parameter=VALUE

范例:读取配置文件设置参数

sysctl -p [/path/to/conf_file]

 

相关内容

    暂无相关文章