pidfile 与 PIDFile 路径不一致时,引起的 redis 无法通过 systemd 启动
问题现象
-
现象1:使用 systemctl 不能正常启动 redis 服务,状态显示为
activating,无法正常进入active(running)状态。 -
现象2:手动执行 redis 进程启动命令:
redis-server /etc/redis/redis.conf能正常启动和提供服务。
排查结果
redis 配置文件中使用 pidfile 指定的文件路径 和 systemd service 配置文件中 PIDFile 指定的路径不一致导致的。
因为 redis 配置文件中指定 redis 采用守护进程模式运行(daemonize yes),systemd 中 service 要托管守护进程时,需要使用 forking 这种启动模式,并且还要配置 PIDFile 来指定,需要托管哪个进程。
如果这个PIDFile 指定路径下的文件不存在,systemd 就不知道要托管哪个进程,也就导致了无法正常启动。
注意:PIDfile 指令指定一个文件时,只会去这个文件中读取进程的PID,不会去创建,创建是 进程自己干的事。
知识补充
linux 中的三种进程类型
-
前台进程:在当前终端直接运行命令启动的进程,会独占当前终端,在进程生命周期结束前,没法使用这个终端做其他操作;终端关闭,该进程也就跟着结束了,因为它是做为当前终端子进程的形式运行的,父进程结束后,会给子进程发送 HUB 信号,收到后也就结束了。
-
后台进程:就是将前台进程放在后台执行,从而释放当前终端,可以用这个终端执行其他任务;但是终端关闭,这个后台进程还是会结束,因为它还是终端的子进程,终端结束发的HUB信号,它还是能收到和处理。
-
守护进程:一种特殊的后台进程,它脱离了终端的控制,不再是终端的子进程,收不到终端信号,所以能独立长期运行。
守护进程的创建流程:
- 简单理解就是先使用指令创建 进程A,进程A 会fork(复制)一个子进程B,然后进程A退出,由进程B来提供服务。
service 的三种启动类型
systemd 是现代 linux 操作系统启动的第一个用户进程,也就是
PID=1的进程,systemd 通过 资源管理单元(unit)来对系统资源进行管理。service 这种 unit 是用来运行、管理守护进程的,也就是某个进程要长期提供服务,可以通过 service 来进行托管。
systemd 的 service 通过编写配置文件来托管进程服务,配置文件采用
Section(节)来进行组织。在
[Service]这个Section中,通过ExecStart来指定通过哪个指令来启动需要托管的进程,通过Type来指定采用何种方式启动这个进程。
simple 类型:
- 默认的启动方式,前台进程、后台进程采用这种启动方式
- 这种启动方式就是如果通过 ExecStart 指定的指令成功执行了,就认为启动成功了,状态显示为:
active(running)
notify 类型:
- 和 simple 一样,只不过 通过
ExecStart指定的指令成功执行了后,这个进程会主动给systemd发送一个信号,说自己已经准备好了,此时才会显示启动成功。 - 如果某个进程不会给 systemd 发信号,用这个启动方式会出现一直卡在
activating状态。
forking 类型:
- 这种方式是用来托管守护进程的,如果某个进程采用守护进程的方式运行,就需要使用这种启动方式。
- 通过
ExecStart指定的指令启动的进程是进程A,然后进程A 在fork子进程(进程B)退出的时候,会将进程B的PID写入一个文件,具体在哪里,一般是由配置文件指定的路径。 - 然后 systemd 还需要使用 PIDFile 指令去指定从哪里找这个进程的
PID,从而确定要托管的进程。如果找不到就会一直卡在activating状态。
浙公网安备 33010602011771号