Day27-Linux系统服务管理
- 1. ltrace:跟踪进程调用库函数
- 2. 进程管理总结
- 3. 什么是平均负载
- 4. 可运行状态和不可中断状态是什么
- 5. 平均负载其实就是【单位时间内的活跃进程数】。
- 6. 如何查看Linux系统的cpu核数和颗数?
- 7. 平均负载案例分析实战
- 7.1 场景一:CPU 密集型进程
- 7.2 场景二:I/O 密集型进程
- 7.3 场景三:大量进程的场景 高并发场景
- 8. 日常故障排查流程(含日志)
- 9. 那平均负载为多少时合理
- 10. Linux系统服务管理知识
- 10.1 什么是Linux运行级别?
- 10.2 运行级别
- 10.3 切换运行级别
- 10.3.1 C6:
- 10.3.2 C7:
- 11. Linux系统Systemd知识
- 11.1 什么是systemd?
- 11.2 为什么要用 systemd?
- 11.3 使用systemd的优势
- 11.4 systemd相关路径文件
- 11.5 systemd管理服务相关命令
- 11.6 systemd文件格式
- 11.7 自定义nginx的systemd启动文件
- 11.8 Linux启动流程
1. ltrace:跟踪进程调用库函数
ltrace 能够跟踪进程的库函数调用,它会显现出哪个库函数被调用,而strace则是跟踪进程的每个系统调用。
参数选项 | 解释说明(带※的为重点) |
---|---|
-c | 统计库函数每次调用时间,最后程序退出时打印摘要 |
-C | 解码低级别名称(内核级)为用户级名称 |
-d | 打印调试信息 |
-e expr | 输出过滤器,通过表达式,可以过滤掉你不想要的输出※ |
-e printf | 表示只查看printf函数调用 |
-e !printf | 表示查看除printf函数以外的所有函数调用 |
-f | 跟踪子进程 |
-o filename | 将ltrace的输出写入文件filename |
-p pid | 指定要跟踪的进程pid※ |
-r | 输出每一个调用的相对时间 |
-S | 显示系统调用 |
-t | 在输出中的每一行前加上时间信息。例子:16:45:28 |
-tt | 在输出中的每一行前加上时间信息,精确到微秒。例子:11:18:59.759546 |
-ttt | 在输出中的每一行前加上时间信息,精确到微秒,而且时间表示为unix时间戳。例子:1486111461.650434 |
-T | 显示每次调用所花费的时间 |
-u username | 以username 的UID和GID执行被跟踪的命令 |
ltrace -o nginx.log /application/nginx/sbin/nginx
2. 进程管理总结
- 找出有问题的进程
top ps pstree pgrep
- 调整优先级
nice renice
- 杀进程
kill,killall,pkill
- 进程前后台切换
ctrl+z,bg,fg,jobs,kill %1
& 后台运行
nohup 配合&,让程序放到后台运行,并且打印输出到日志里。
screen #保持操作的会话,使之不中断。运维人员客户端xshell用。
- 进程里面在干什么(nginx php mysql)
strace,lstrace,gdb
平均负载(load average)
top,w,uptime
平时只看负载就看uptime
[root@oldboy ~]# uptime
11:24:23 up 5 days, 12:59, 3 users, load average: 0.00, 0.01, 0.05
[root@oldboy ~]# cat /proc/loadavg
0.00 0.01 0.05 1/148 83035
3. 什么是平均负载
平均负载不是单位时间内的CPU使用率吗?
衡量系统繁忙的一个综合指标,主要是CPU,IO的繁忙程度。工作中非常常用,具体哪个指标繁忙
ps,top,sar看CPU。
iostat,iotop看磁盘。
一个进程产生到持续运行要是占用很多资源;1.PID,2.内存,3.文件描述符,4.CPU,5.磁盘
平均负载是指单位时间内,系统处于可运行状态和不可中断状态的平均进程数,也就是平均活跃进程数。
系统平均负载被定义为在特定时间间隔内【CPU运行队列中的平均进程数】。如果一个进程满足以下条件则其就会位于运行队列中:
CPU:打饭的阿姨。
进程:排队打饭的学生。
链接: https://developer.aliyun.com/article/294493
车:进程 桥:CPU 队列
一个桥:一个 CPU 队列,1.0
两个桥:两个 CPU 队列,2.0
平均负载数值和CPU核数相等的时候就是CPU处理进程临界点
2颗,每颗4核,8核,负载为8的时候,临界点。8*70%=5.6 (5-8) 慢的临界点
STAT:该进程目前的状态,主要的状态包括
- R :正在运行或者是可被运行。
- S :正在中断睡眠中,可被某些信号(signal) 唤醒。
- D :不可中断睡眠。
- T :正在侦测或者是停止了。
- Z :已经终止,但是其父进程无法正常终止他,造成 zombie (疆尸) 进程的状态。
4. 可运行状态和不可中断状态是什么
- 可运行状态进程:
是指正在被CPU处理或者正在等待CPU处理的进程,
ps命令看到处于R状态的进程。可运行状态: S R 占用cpu - 不可中断进程,
系统中最常见的是等待硬件设备的I/O响应,
ps命令中看到的D 状态进程。
5. 平均负载其实就是【单位时间内的活跃进程数】。
[root@oldboy ~]# uptime
11:45:25 up 5 days, 13:20, 3 users, load average: 0.00, 0.01, 0.05
2颗,单颗4核CPU为例:
1分钟:10.00 #CPU处理进程1分钟的繁忙程度,忙碌1分钟。
5分钟:8.01 #CPU处理进程5分钟的繁忙程度,忙碌了5分钟
15分钟:5.05 #CPU处理进程15分钟的繁忙程度,忙碌持续15分钟,15分钟内平均值5.
uptime:故障恢复了。
1分钟:1.00 #CPU处理进程1分钟的繁忙程度,忙碌1分钟。
5分钟:8.01 #CPU处理进程5分钟的繁忙程度,忙碌了5分钟
15分钟:5.05 #CPU处理进程15分钟的繁忙程度,忙碌持续15分钟,15分钟内平均值5.
总结:15分钟负载值12,是高是低呢
负载数值/总的核心数=1 #开始慢的临界点,实际上1*70%==关注的临界点。
12/8=1.2 大于1就说明有问题。(8核)
负载不要超过5,是临界点。
2颗单颗4核CPU,共8核,负载就是8*70%=5左右。
需要关注负载的值:总的核心数*70%=关注的点
要掌握的
1.平均负载是运行队列中活跃的进程数。
2.平均负载,1,5,15分钟内的负载。
3.需要关注负载的值:总的核心数*70%=关注的点
4.辅助top,ps,uptime,sar,mpstat,pidstat,iostat,排查问题。
5.strace跟踪进程系统调用。
6.记住几个案例(面试讲故事)。
面试官问:
你在工作中遇到过哪些生产故障,是怎么解决的?
最好和数据库相关(负载高),和web相关(PHP进程100%,JAVA内存泄漏)
要掌握的
如何查CPU核心数?
查看物理CPU个数,uniq是去重的意思:
grep "physical id" /proc/cpuinfo|wc -l
grep -c "physical id" /proc/cpuinfo
查看每个物理CPU中core的个数(即核数):
grep "cpu cores" /proc/cpuinfo|wc -l
#查看逻辑CPU的个数(用于计算负载)
grep "processor" /proc/cpuinfo|wc -l
6. 如何查看Linux系统的cpu核数和颗数?
#解答
1.top 按1
2.lscpu
#查看物理CPU个数,uniq是去重的意思:
grep "physical id" /proc/cpuinfo|wc -l
#查看每个物理CPU中core的个数(即核数):
grep "cpu cores" /proc/cpuinfo|wc -l
#查看逻辑CPU的个数
grep "processor" /proc/cpuinfo|wc -l
7. 平均负载案例分析实战
用 stress、mpstat、pidstat 等工具,找出平均负载升高的根源
stress是Linux系统压力测试工具,这里我们用作异常进程模拟平均负载升高的场景。
mpstat是【多核CPU性能分析工具】,用来实时查看每个CPU的性能指标,以及所有CPU的平均指标。
pidstat是一个常用的【进程性能分析工具,用来实时查看进程的CPU、内存、I/O 以及上下文切换等性能指标。
yum install stress -y
yum install sysstat -y
[root@oldboy ~]# rpm -ql sysstat|grep bin
/usr/bin/iostat ###*****
/usr/bin/mpstat ###*****
/usr/bin/pidstat ###*****
/usr/bin/sar ###*****端午作业总结:
3个案例:整理大家感受下。
分析完这三个案例,我再来归纳一下平均负载与CPU
平均负载提供了一个快速查看系统整体性能的手段,反映了整体的负载情况。
但只看平均负载本身,并不能直接发现,到底是哪里出现了瓶颈。所以,在理解平均负载时,也要注意:
平均负载高有可能是CPU密集型进程导致的;
平均负载高并不一定代表CPU使用率高,还有可能是 I/O 更繁忙了;
当发现负载高的时候,你可以使用 mpstat、pidstat等工具,辅助分析负载的来源****
sar
6.平均负载案例分析实战
下面,我们以三个示例分别来看这三种情况,并用 stress、mpstat、pidstat 等工具,找出平均负载升高的根源。
stress 是 Linux 系统压力测试工具,这里我们用作异常进程模拟平均负载升高的场景。
mpstat 是多核 CPU 性能分析工具,用来实时查看每个 CPU 的性能指标,以及所有 CPU 的平均指标。
pidstat 是一个常用的进程性能分析工具,用来实时查看进程的 CPU、内存、I/O 以及上下文切换等性能指标。
#如果出现无法使用mpstat、pidstat命令查看%wait指标建议更新下软件包
yum install sysstats -y
yum install stress -y
stress --cpu 8 --io 4 --vm 2 --vm-bytes 128M --timeout 10s
7.1 场景一:CPU 密集型进程
1.首先,我们在第一个终端运行 stress 命令,模拟一个 CPU 使用率 100% 的场景:
[root@oldboy ~]# stress --cpu 1 --timeout 600
2.接着,在第二个终端运行 uptime 查看平均负载的变化情况
# 使用watch -d 参数表示高亮显示变化的区域(注意负载会持续升高)
[root@oldboy ~]# watch -d uptime
3.最后,在第三个终端运行 mpstat 查看 CPU 使用率的变化情况
# -P ALL 表示监控所有CPU,后面数字5 表示间隔5秒后输出一组数据
[root@oldboy ~]# mpstat -P ALL 5
#单核CPU,所以只有一个all和0
4.从终端二中可以看到,1 分钟的平均负载会慢慢增加到 1.00,而从终端三中还可以看到,正好有一个 CPU 的使用率为 100%,但它的 iowait 只有 0。这说明,平均负载的升高正是由于 CPU 使用率为 100% 。那么,到底是哪个进程导致了 CPU 使用率为 100% 呢?可以使用 pidstat 来查询
# 间隔5秒输出一组数据
[root@oldboy ~]# pidstat -u 5 1
#从这里可以明显看到,stress进程的CPU使用率为100%。
- 模拟cpu负载高
stress --cpu 1 --timeout 100
- 通过uptime或w 查看
watch -d uptime
- 查看整体状态mpstat -P ALL 1 查看每个cpu核心使用率
- 精确到进程: pidstat 1
7.2 场景二:I/O 密集型进程
1.首先还是运行 stress 命令,但这次模拟 I/O 压力,即不停地执行 sync
[root@oldboy ~]# stress --io 1 --timeout 600s #利用sync()
stress --hdd 8 --hdd-bytes 1g # hd harkdisk 创建进程去进程写
2.然后在第二个终端运行 uptime 查看平均负载的变化情况:
[root@oldboy ~]# watch -d uptime
18:43:51 up 2 days, 4:27, 3 users, load average: 1.12, 0.65, 0.00
3.最后第三个终端运行 mpstat 查看 CPU 使用率的变化情况:
# 显示所有 CPU 的指标,并在间隔 5 秒输出一组数据
[root@oldboy ~]# mpstat -P ALL 5
#会发现cpu的与内核打交道的sys占用非常高
4.那么到底是哪个进程,导致 iowait 这么高呢?我们还是用 pidstat 来查询
# 间隔5秒后输出一组数据,-u 表示CPU指标
[root@oldboy ~]# pidstat -u 5 1
#可以发现,还是 stress 进程导致的。
- 通过stress 模拟大量进程读写
stress --hdd 4
- 通过w/uptime查看系统负载信息
watch -d uptime
- 通过top/mpstat 排查
mpstat -P ALL 1 或 top 按1
- 确定是iowati
iostat 1查看整体磁盘读写情况 或iotop -o 查看具体哪个进程读写
- 根据对应的进程,进行相关处理.
7.3 场景三:大量进程的场景 高并发场景
当系统中运行进程超出 CPU 运行能力时,就会出现等待 CPU 的进程。
1.首先,我们还是使用 stress,但这次模拟的是 4 个进程
[root@oldboy ~]# stress -c 4 --timeout 600
2.由于系统只有 1 个 CPU,明显比 4 个进程要少得多,因而,系统的 CPU 处于严重过载状态
3.然后,再运行 pidstat 来看一下进程的情况:
# 间隔5秒后输出一组数据
[root@oldboy ~]# pidstat -u 5 1
可以看出,4个进程在争抢 1 个 CPU,每个进程等待 CPU 的时间(也就是代码块中的 %wait 列)高达 75%。这些超出 CPU 计算能力的进程,最终导致 CPU 过载。
分析完这三个案例,我再来归纳一下平均负载与CPU
平均负载提供了一个快速查看系统整体性能的手段,反映了整体的负载情况。但只看平均负载本身,我们并不能直接发现,到底是哪里出现了瓶颈。所以,在理解平均负载时,也要注意:
平均负载高有可能是 CPU 密集型进程导致的;
平均负载高并不一定代表 CPU 使用率高,还有可能是 I/O 更繁忙了;
当发现负载高的时候,你可以使用 mpstat、pidstat 等工具,辅助分析负载的来源
系统负载的计算和意义
进程以及子进程和线程产生的计算指令都会让cpu执行,产生请求的这些进程组成"运行队列",等待cpu执行,这个队列就是系统负载, 系统负载是所有cpu的运行队列的总和.
[root@oldboyedu ~]# w
20:25:48 up 95 days, 9:06, 1 user, load average: 2.92, 0.00, 0.00
假设当前计算机有4个核心的cpu,当前的负载是2.92
cpu1 cpu2 cpu3 cpu4
2.94/4(个cpu核心) = 73%的cpu资源被使用,剩下27%的cpu计算资源是空想的
假设当前的计算有2个核心的cpu,当前的负载是2.92
2.92/2 = 146% 已经验证超过了cpu的处理能力
8. 日常故障排查流程(含日志)
- w/uptime, 查看负载
- ps aux/top 看看 cpu百分比, io wait或者是内存占用的高? (三高 cpu,io,内存)
- top检查具体是哪个进程,找出可疑进程
- 追踪这个进程使用情况,做什么的?
- 看看对应日志是否有异常
- 系统日志: /var/log/messages(系统通用日志) /var/log/secure(用户登录情况)
- 服务软件的日志
9. 那平均负载为多少时合理
最理想的状态是每个 CPU核心 上都刚好运行着一个进程,这样每个 CPU 都得到了充分利用。所以在评判平均负载时,首先你要知道系统有几个 CPU核心,这可以通过 top 命令获取,或grep 'model name' /proc/cpuinfo
系统平均负载被定义为在特定时间间隔内运行队列中的平均进程数。如果一个进程满足以下条件则其就会位于运行队列中:
- 它没有在等待I/O操作的结果
- 它没有主动进入等待状态(也就是没有调用’wait’)
- 没有被停止(例如:等待终止)
10. Linux系统服务管理知识
10.1 什么是Linux运行级别?
Linux运行级别
就是Linux系统启动时处于不同状态标识的集合。
例如:文本模式、图形模式、重启模式、关机模式都会对应不同的运行级别,
这个运行级别对于CentOS7之前的具体标识体现为0-6之间的数字。
10.2 运行级别
0-6分别是啥
查看运行级别及对应的target
[root@oldboy ~]# ls -l /usr/lib/systemd/system/runlevel[0-9].target
lrwxrwxrwx. 1 root root 15 Dec 4 2023 /usr/lib/systemd/system/runlevel0.target -> poweroff.target
lrwxrwxrwx. 1 root root 13 Dec 4 2023 /usr/lib/systemd/system/runlevel1.target -> rescue.target
lrwxrwxrwx. 1 root root 17 Dec 4 2023 /usr/lib/systemd/system/runlevel2.target -> multi-user.target
lrwxrwxrwx. 1 root root 17 Dec 4 2023 /usr/lib/systemd/system/runlevel3.target -> multi-user.target
lrwxrwxrwx. 1 root root 17 Dec 4 2023 /usr/lib/systemd/system/runlevel4.target -> multi-user.target
lrwxrwxrwx. 1 root root 16 Dec 4 2023 /usr/lib/systemd/system/runlevel5.target -> graphical.target
lrwxrwxrwx. 1 root root 13 Dec 4 2023 /usr/lib/systemd/system/runlevel6.target -> reboot.target
10.3 切换运行级别
10.3.1 C6:
1)查看运行级别
root@oldboy ~]# runlevel
N 3
2)切换运行级别
[root@oldboy ~]# init 5
[root@oldboy ~]# runlevel
3 5
startx #切换到桌面
启动时加载的文件(C5)
/etc/inittab
默认运行级别在/etc/inittab里设置。
id:3:initdefault: #<==系统启动时,将Linux设定固定的运行级别的配置行。
10.3.2 C7:
[root@oldboy ~]# systemctl get-default
multi-user.target ##当前级别3。
设置开机默认运行的级别target
# systemctl set-default TARGET.target
[root@oldboy ~]# systemctl set-default multi-user.target
Removed symlink /etc/systemd/system/default.target.
Created symlink from /etc/systemd/system/default.target to /usr/lib/systemd/system/multi-user.target.
11. Linux系统Systemd知识
11.1 什么是systemd?
Systemd(System Daemon)是CentOS7系统中的系统管理守护进程、工具和库的集合,用于取代早期的init进程。Systemd的功能是用于集中管理和配置Linux系统。
systemd是CentOS7系统中启动的第一个进程(PID等于1),其他所有进程都是他的子进程。
C6:服务启动方式
[root@oldboy ~]# /etc/init.d/network restart
Restarting network (via systemctl): [ OK ]
[root@oldboy ~]# service network restart
Restarting network (via systemctl): [ 确定 ]
11.2 为什么要用 systemd?
早在CentOS7之前,采用 init 进程作为系统启动后的第一个进程,但是用 init 启动方式有两个缺点:
1.启动时间长,因为 init 进程是串行执行的,只有前一个进程启动完毕后一个进程才启动。
2.启动脚本复杂,以前的系统初始化需要加载很多脚本,依赖关系复杂,靠脚本自己处理。
3.相关的管理命令很多,很杂。
Systemd 就是为了解决上述问题而诞生的。它的设计目标是,为系统启动和管理提供一套完整的解决方案。
从 Centos5 到 Centos7,Centos5 系统的启动速度最慢的,因为是串行启动,无论进程相互之间有无依赖关系。Centos6 系统的启动速度有所提高。有依赖的进程之间依次启动而其他与之没有依赖关系的则并行同步启动。Centos7 系统开始,所有进程无论有无依赖关系则都是并行启动。
11.3 使用systemd的优势
- Centos7实现开机并行启动,显著提高开机启动速度。
- 自动解决启动间的服务依赖关系。
- 服务的启动配置文件统一语法,管理起来更方便。
- systemd 较好的解决原有模式缺陷,比如原有 service 不会关闭程序产生的子进程
- 从 Debian9、Centos7、Ubunut16 等系统开始,都开始使用 systemd 来管理服务。
- Centos7 服务的启动与停止不在使用脚本管理服务,也就是/etc/iit.d下不在有脚本。
11.4 systemd相关路径文件
路径 | 描述 |
---|---|
/usr/lib/systemd/system | /etc/init.d(启动服务程序所在的路径) |
/etc/systemd/system | /etc/rc.d(不同运行级别启动文件路径) |
/etc/systemd/system/multi-user.target.wants | /etc/rc.d/rc3.d(3级别路径),文本模式 |
11.5 systemd管理服务相关命令
systemctl管理服务的启动、重启、停止、重载、查看状态等常用命令
systemctl命令 | 作用 |
---|---|
systemctl start crond.service | 启动服务 |
systemctl stop crond.service | 停止服务 |
systemctl restart crond.service | 重启服务 |
systemctl reload crond.service | 重新加载配置 |
systemctl status crond.service | 查看服务运行状态 |
启动状态0.
状态 | 描述 |
---|---|
loaded | 服务单元的配置文件已经被处理 |
active(running) | 服务持续运行 |
inactive (dead) | 服务停止状态 |
enabled | 服务设定为开机运行 |
disabled | 服务设定为开机不运行 |
systemctl 设置服务开机启动、不启动命令
systemctl命令 | 作用 |
---|---|
systemctl enable crond.service | 开机自动启动 |
systemctl disable crond.service | 开机不自动启动 |
systemctl 设置服务开机启动、不启动命令原理:
systemctl enable crond.service #原理,就是创建一个软链接
systemctl disable crond.service #原理,就是移除一个软链接
[root@oldboy ~]# systemctl enable crond
Created symlink from /etc/systemd/system/multi-user.target.wants/crond.service to /usr/lib/systemd/system/crond.service.
[root@oldboy ~]# systemctl disable crond
Removed symlink /etc/systemd svstem/multi-user.target.wants/crond.service
手工设置开机自启动。
在/etc/systemd/system/multi-user.target.wants/下设置快捷方式。
[root@oldboy ~]# ln -s /usr/lib/systemd/system/crond.service /etc/systemd/system/multi-user.target.wants/crond.service
[root@oldboy ~]# ls -l /etc/systemd/system/multi-user.target.wants/|grep crond
lrwxrwxrwx. 1 root root 37 Jun 9 01:23 crond.service -> /usr/lib/systemd/system/crond.service
[root@oldboy ~]# systemctl status crond
* crond.service - Command Scheduler
Loaded: loaded (/usr/lib/systemd/system/crond.service; 【enabled】; vendor preset: enabled)
Active: inactive (dead)
手工设置开机停止启动。
删除在multi-user.target.wants里的快捷方式。
[root@oldboy ~]# rm -f /etc/systemd/system/multi-user.target.wants/crond.service ##
[root@oldboy ~]# ls -l /etc/systemd/system/multi-user.target.wants/|grep crond
[root@oldboy ~]# systemctl status crond
* crond.service - Command Scheduler
Loaded: loaded (/usr/lib/systemd/system/crond.service; 【disabled】; vendor preset: enabled)
Active: inactive (dead)
systemctl保留开机启动的服务
rsyslog.service enabled
sshd.service enabled
sysstat.service enabled
处理方法:
systemctl list-unit-files|egrep -v "network.ta|rsyslog|sshd\.|sysstat|static"|awk '{print "systemctl disable "$1}'|bash
systemctl list-unit-files|grep enabled
[root@oldboy ~]# systemctl list-unit-files|grep enabled
rsyslog.service (日志系统) enabled
sshd.service (远程连接SSHD) enabled
sysstat.service (性能监控) enabled
network (网络服务),使用chkconfig开启。
还要开启网络服务的开机自启动
systemctl enable netwrok ####
chkconfig network on #23454个级别上开机自启动,centos7以前的设置开机自启动的命令。
[root@oldboy ~]# chkconfig --list|grep network
network 0:off 1:off 2:on 3:on 4:on 5:on 6:off
linux服务器 开机自启动服务优化
rsyslog.service (日志系统) enabled
sshd.service (远程连接SSHD) enabled
sysstat.service (性能监控) enabled
network (网络服务),使用chkconfig开启。
其他的根据需要开启。
预习:
systemd配置文件
C6启动流程*****
C7启动流程*****
linux单用户模式找回密码
救援模式修复案例(过时了,工作中自动化安装,定制镜像)
11.6 systemd文件格式
1)systemd文件路径说明:
/etc/systemd/system/ #系统启动加载的文件路径
/usr/lib/systemd/system/ #使用rpm软件包安装的软件的启动配置文件目录
2)systemd文件格式说明:
systemd unit文件通常是由三部分组成的
[Unit] #定义通用选项,比如描述信息,依赖关系等。
[Service] #特定服务类型,具体启动、关闭、重启选项都在此部分配置
[Install] #定义由开机自启和不开机自启命令时实现的选项
3)Unit段常用说明:
Description #描述信息
Documentation #说明文档的在线地址
After #定义启动顺序,表示当前配置的服务应该晚于哪些服务之后启动
Wants #依赖其他的服务
更多:
Description:简短描述
Documentation:文档地址
Requires:当前Unit依赖的其他Unit,如果它们没有运行,当前Unit会启动失败
Wants:与当前Unit配合的其他Unit,如果它们没有运行,当前Unit不会启动失败
BindsTo:与Requires类似,它指定的 Unit 如果退出,会导致当前Unit停止运行
Before:如果该字段指定的Unit也要启动,那么必须在当前Unit之后启动
After:如果该字段指定的Unit也要启动,那么必须在当前Unit之前启动
Conflicts:这里指定的Unit 不能与当前Unit同时运行
Condition...:当前Unit运行必须满足的条件,否则不会运行
Assert...:当前Unit运行必须满足的条件,否则会报启动失败
4)Service段常用说明:
Type #定义服务类型
forking #需要父进程启动子进程的服务类型为forking
PIDFile #定义PID文件路径(进程PID)
ExecStart #指定启动服务命令绝对路径
ExecReload #指定重新加载服务的配置文件的命令绝对路径
ExecStop #指定停止服务命令绝对路径
ExecStartPre #在启动之前运行的命令
ExecStartPost #在启动之后运行的命令
5)Install段常用说明:
WantedBy #哪些服务需要被依赖
systemd.unit官方完整说明:
链接: https://www.freedesktop.org/software/systemd/man/systemd.unit.html
6)nginx的systemd启动文件解释:
[Unit]
Description=nginx - high performance web server #说明信息
Documentation=http://nginx.org/en/docs/ #帮助说明
After=network-online.target remote-fs.target nss-lookup.target #需要依赖这些服务,在这些服务启动后启动
Wants=network-online.target #需要依赖的服务
[Service]
Type=forking #启动类型为forking
PIDFile=/var/run/nginx.pid #pid文件的绝对路径
ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf #启动命令的绝对路径
ExecReload=/bin/sh -c "/bin/kill -s HUP $(/bin/cat /var/run/nginx.pid)" #重新加载配置的绝对路径
ExecStop=/bin/sh -c "/bin/kill -s TERM $(/bin/cat /var/run/nginx.pid)" #停止服务命令的绝对路径
[Install]
WantedBy=multi-user.target #需要依赖的服务
自定义服务启动文件:
PIDFile=/var/run/nginx.pid #pid文件的绝对路径
ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf #启动命令的绝对路径
ExecStop=/bin/sh -c "/bin/kill -s TERM $(/bin/cat /var/run/nginx.pid)" #停止服务命令的绝对路径
Centos6 | Centos7 |
---|---|
/etc/init.d/nginx start(纯shell脚本) | systemctl start nginx(systemd启动文件) |
service nginx start | |
chkconfig nginx on chkconfig nginx off | systemctl enable nginx systemctl disable nginx |
chkconfig --list | grep 3:on | systemctl list-unit-files |
/etc/init.d/nginx start
11.7 自定义nginx的systemd启动文件
编译安装nginx过程略。
- 修改nginx配置文件的pid为自定义路径
[root@linux ~]# grep pid /application/nginx/conf/nginx.conf
pid /application/nginx/pid/nginx.pid;
- 写入自定义systemd配置
cat > /usr/lib/systemd/system/oldboy_nginx.service << 'EOF'
[Unit]
Description=DIY nginx
Documentation=https://www.oldboyedu.com/
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/application/nginx/pid/nginx.pid
ExecStart=/application/nginx/sbin/nginx -c /application/nginx/conf/nginx.conf
ExecReload=/bin/sh -c "/bin/kill -s HUP $(/bin/cat /application/nginx/pid/nginx.pid)"
ExecStop=/bin/sh -c "/bin/kill -s TERM $(/bin/cat /application/nginx/pid/nginx.pid)"
ExecStartPre=/bin/sh -c "/usr/bin/chown -R www:www /application/nginx/"
[Install]
WantedBy=multi-user.target
EOF
- 重新加载systemd配置
systemctl daemon-reload
- 启动我们自定义的服务
systemctl start oldboy_nginx
systemctl status oldboy_nginx
kill命令生产应用:
ExecReload=/bin/sh -c "/bin/kill -s HUP $(/bin/cat /var/run/nginx.pid)" #重新加载配置的绝对路径,平滑生效。
ExecStop=/bin/sh -c "/bin/kill -s TERM $(/bin/cat /var/run/nginx.pid)" #停止服务命令的绝对路径
已知某人开发的nginx启动脚本/etc/init.d/nginx start
如何配置脚本,能让脚本使用chkconfig 进行开机自启动设置。
答:
#chkconfig: 2345 21 81
#description: rsync service start and stop scripts
自定义一个nginx脚本
cat >/usr/lib/systemd/system/oldboy_nginx.service <<EOF
[Unit]
Description=DIY nginx
Documentation=https://www.oldboyedu.com/
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
ExecStart=/application/nginx/sbin/nginx -c /application/nginx/conf/nginx.conf
ExecReload=/application/nginx/sbin/nginx -s reload
ExecStop=/application/nginx/sbin/nginx -s stop
ExecStartPre=/bin/sh -c "/usr/bin/chown -R www:www /application/nginx/"
[Install]
WantedBy=multi-user.target
EOF
[root@oldboy ~]# cat /usr/lib/systemd/system/oldboy_nginx.service
[Unit]
Description=DIY nginx
Documentation=https://www.oldboyedu.com/
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
ExecStart=/application/nginx/sbin/nginx -c /application/nginx/conf/nginx.conf
ExecReload=/application/nginx/sbin/nginx -s reload
ExecStop=/application/nginx/sbin/nginx -s stop
ExecStartPre=/bin/sh -c "/usr/bin/chown -R www:www /application/nginx/"
[Install]
WantedBy=multi-user.target
11.8 Linux启动流程
第一步:开启开机按钮,计算机加载BIOS自检
第二步:读取MBR信息
第三步:加载grub菜单(Boot Loader,引导加载程序)
[root@oldboy boot]# cat /etc/grub.conf #<==也可读取/boot/grub/menu.lst或/boot/grub/grub.conf
....省略多行注释信息,其实这里的注释已经解释的蛮清楚了,只是 90%的初学者看不见这里...
default=O #<==默认情况下如何加载系统,0表示加载菜单中对应的第一个名字,多系统时可以调节默认加载项。
timeout=5 #<==表示多少秒之后开始加载默认的系统,给管理员提前选择的时间。
splashimage=(hd0,0)/grub/splash.xpm.gz #<==启动时显示的背景图标,在(hd0,0)代表/boot 分区。
hiddenmenu #<==系统启动时,会隐藏启动菜单信息,按默认设置启动系统,除非用户按键干预。
password [ -md5 - encrypted ] STRING #<==当编辑 grub 菜单时需要认证,Linux 优化之一,默认没有。
title Cent0S 6 (2.6.32-696.e16.x86 64) #<==要启动的系统对应的项目名称,可按需修改
root (hd0,0) #<==引导内核文件和内核所需骤动文件所在的分区,(hd0,0)代表/boot 分区
#<=其中 hd0 表示计算机的第一块磁盘,(hd0,0)中逗号后面的0表示第一个分区,即(hd0,0)表示第一块磁盘的第一个分区,即/dev/sdal (分区通常最先独立分出的/boot分区,对应的设备名就是sdal)。
kernel /vmlinuz-2.6.32-696.el6.x86_64 ro root=UUID=491eabe5-e6c0-4457-9bdb-b37cc6751308rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=autoKEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet #<==位于 boot 分区上的内核文件,及一堆可选内核参数。
#<==/mlinuz-2.6.32-696.el6.x86_64 为内核文件。root=UUID=后面一串数字表示根对应的设备信息(/dev/sda3),其他介绍的作用不大,忽略即可。
initrd /initramfs-2.6.32-696.e16.x86_64.img #<==内核启动所需的驱动文件的所在地,存在于 boot区
第四步:加载kernel内核以及驱动程序
根据 grub 设定的内核映像所在路径,系统会读取内存映像,并进行解压缩操作。当解压缩内核完成后,屏幕输出"OK,booting the kernel"。其实就是根据 grub.conf 中的如下设置加载内核及相关参数:
kernel /vmlinuz-2.6.32-696.el6.x86_64 ro root=UUID=491eabe5-e6c0-4457-9bdb-b37cc6751308rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=autoKEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
此外,还会加载内核所需的驱动程序文件,进而挂载并读取根分区的信息,加载操作系统文件。示例如下:
initrd /initramfs-2.6.32-696.e16.x86_64.img
第五步:
(C6)启动init进程,读取inittab文件
(C7)启动systemd进程,加载如下文件