- A+
回顾历史
在linux发展的历史长河中,按照顺序依次出现过三种系统初始化机制,分别是:SysV init,Upstart,Systemd。不需要深究机制这个词是不是准确。
所谓系统初始化机制,就是它们决定了在系统初始化时候,执行什么操作以及按照什么顺序来执行这些操作。三种系统初始化机制各有优缺点,但是后浪总是会把前浪拍在沙滩上。以下优缺点引用自“网络”
- SysV init
SysV init中的服务串行按照顺序启动,保证脚本执行顺序,也方便调试和排错。但也因为串行启动,导致系统启动时间过长,在linux被应用到移动端后这个缺点成了大问题。
- Upstart
upstart通过并行启动加快执行速度,但对于相互依赖的服务仍然采用并发启动。它也支持硬件热插拔时的动态启动和卸载。
- Systemd
相比于upstart,systemd对于相互依赖的服务它也支持并行启动。它的按需启动比upstart更优秀。
这时候有人脑海里面就会闪现出一个问题:如何判断某个linux系统采用了哪种初始化系统?
因为系统初始化进程是linux启动的第一个进程,其pid始终为1,因此可以从/proc/1/文件夹中获取到一些蛛丝马迹。在/proc目录中,有一个名称为exe的文件(和windows系统没有半毛钱关系)。
exe文件指向启动当前进程的可执行文件(完整路径)的符号链接。通过查看exe文件的指向,可以知道当前系统所使用的初始化系统类型。
以下是在两种不同初始化系统上执行stat /proc/1/exe
所得到的结果。从第二行结果可知,第一个系统采用的是Systemd,第二个系统采用的是SysV init初始化(init为其可执行文件)。
为什么例子中没有Upstart?因为找不到Upstart的系统
[root@ip-172-31-8-32 ~]# stat /proc/1/exe File: ‘/proc/1/exe’ -> ‘/usr/lib/systemd/systemd’ Size: 0 Blocks: 0 IO Block: 1024 symbolic link Device: 3h/3d Inode: 66971739 Links: 1 Access: (0777/lrwxrwxrwx) Uid: ( 0/ root) Gid: ( 0/ root)
root@ip-172-31-9-10:/proc/1# stat /proc/1/exe File: /proc/1/exe -> /init Size: 0 Blocks: 0 IO Block: 1024 symbolic link Device: 33h/51d Inode: 81 Links: 1 Access: (0777/lrwxrwxrwx) Uid: ( 0/ root) Gid: ( 0/ root)
我是谁?我在哪里?应该到哪里去?
当明确了当前linux系统的初始化系统后,紧接着第二个问题接踵而至:怎么做才能让初始化系统知道,在系统启动后要运行kafka或者nginx?
答案和把一头大象装入冰箱一样:1. 打开冰箱门 2. 把大象装进去 3. 关闭冰箱门
但是细节呢?细节就是1、完成服务脚本 2、将服务脚本放在固定的位置
,下面是不同初始化系统放置服务脚本的位置
SysV init | Upstart | Systemd |
---|---|---|
/etc/init.d | /etc/init | /etc/rc.d/init.d |
下面一一更详细解释
SysV init
- 编写服务脚本。服务脚本主体采用shell语法编写,一般应用程序都会提供自启动脚本。下面为一段例子脚本
#!/bin/bash #service hello start() { echo 'start hello service...' echo 'start hello service over' } stop() { echo 'stop hello service...' echo 'stop hello service over' } case $1 in start) start ;; stop) stop ;; restart) stop start ;; *) echo "valid arg:[start|status|stop|restart]" esac exit 0
- 将其放在
/etc/init.d
目录中。service --status-all
命令,会列举/etc/init.d目录中所有服务。以下结果说明,系统已经认识了服务hello
root@ip-172-31-9-10:/etc/init.d# service --status-all [ - ] apparmor [ ? ] apport [ - ] dbus [ - ] hello [ ? ] hwclock.sh ...
- 使用命令
chkconfig --add hello
将服务hello添加到开机启动中。 /etc目录有6个子目录,可以指定init.d目录中所包含服务脚本的执行场景。
目录 | level | 执行场景 |
---|---|---|
rc0.d | 0 | 关机 |
rc1.d | 1 | 单用户模式 |
rc2.d | 2 | 无网络连接的多用户命令行模式 |
rc3.d | 3 | 有网络连接的多用户命令行模式 |
rc4.d | 4 | 系统保留 |
rc5.d | 5 | 带图形界面的多用户模式 |
rc6.d | 6 | 重新启动 |
每个目录中的文件都链接至init.d目录中的服务脚本。以下为rc0.d目录内容,其显示在关机场景时,将rc0.d目录中所有的服务关闭(K-kill)
root@weidengbai:/etc/rc0.d# ls -l total 0 lrwxrwxrwx 1 root root 13 Apr 23 2020 K01atd -> ../init.d/atd lrwxrwxrwx 1 root root 20 Apr 23 2020 K01cryptdisks -> ../init.d/cryptdisks lrwxrwxrwx 1 root root 25 Apr 23 2020 K01multipath-tools -> ../init.d/multipath-tools lrwxrwxrwx 1 root root 15 Mar 25 09:48 K01nginx -> ../init.d/nginx ....
当运行chkconfig --add hello
命令时,chkconfig 会自动创建对应目录的软连接。