手把手制作 nginx 自启动脚本
写在前面
对于赶时间的同学,直接 copy 下面的代码并保存到 /lib/systemd/system/nginx.service 中,然后执行 sudo systemctl enable nginx.service
即可。
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/usr/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
注:以上启动脚本仅适用于使用 systemd 的系统,如果是其他 init 系统,例如 upstart,可以参考这里。
Systemd 简介
systemd is a system and service manager for Linux operating systems. When run as first process on boot (as PID 1), it acts as init system that brings up and maintains userspace services.
Systemd 是 init system 之一,除了 systemd,还有 upstart、SysVinit 等。Systemd 被设计用来代替 upstart 和 SysVinit。下面 systemd 的整体架构图:
Systemd 可以管理所有的系统资源,在 systemd 中资源有一个统一的名称 “Unit”。
# 列出正在运行的 Unit
systemctl list-units
# 列出所有Unit,包括启动失败的
systemctl list-units --all
在 systemd 管理的 units 中,其中有一种称之为 service,可以认为 service 是受 systemd 管理和监控的进程。如果想让 systemd 管理我们的进程,我们需要给 systemd 提供一个配置文件,这个配置文件以 .service 作为后缀,例如我们想让 systemd 管理我们的 nginx 进程,我们可以编写一个 nginx.service 配置。
列出系统中的 service
systemctl list-units --type=service
从上面的架构图可以看出,systemd 提供了很多工具类,其中很重要的一个是 sytemctl,我们可以利用该工具管理 service,下面以管理 nginx 为例:
# 启动 nginx 服务
sudo systemctl start nginx.service
# 停止 nginx 服务
sudo systemctl stop nginx.service
# 重启 nginx 服务
sudo systemctl restart nginx.service
# 杀死 nginx 所有子进程
sudo systemctl kill nginx.service
# 重新加载 nginx 配置文件
sudo systemctl reload nginx.service
# 开机自启动 nginx
sudo systemctl enable nginx.service
# 取消开机自启动 nginx
sudo systemctl disable nginx.service
手把手制作 nginx 自启动脚本
其实叫做自启动脚本并不合适,nginx.service 文件只是提供给 systemd 管理 nginx 服务的一个配置文件,然后我们可以使用 systemctl 命令管理 nginx,开机自启动只是 systemd 管理 nginx 服务中一种功能而已。下面上我们来拆解下上面的 nginx.service 文件,先看 [Unit] 部分:
[Unit] 部分
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
Description 用来描述服务的内容,这个没什么好说的。After 用来管理服务依赖,但只是弱依赖,即便依赖的服务未启动也不影响本服务的启动。如果想使用强依赖关系,可以使用 Require。Wants 类似于 Require 但是 Wants 指定的依赖是弱依赖。Require 和 Wants 没有规定启动顺序,Before 和 After 则规定了启动顺序。
[Service] 部分
[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/usr/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Service] 部分是重头戏,他告诉了 systemd 该如何管理服务(启动、停止、重新加载配置文件等):
- Type:forking 表示启动的服务进程是守护进程,这种进程启动后会持续在后台默默运行。type 还支持 simple/exec/oneshot,请自行搜索相关说明;
- PIDFile:指定服务的 pid 文件,type 为 forking 的服务推荐配置该选项;
- ExecStartPre:在启动服务之前执行的命令;
- ExecStart:启动服务的命令;
- ExecReload:重新加载服务配置文件的命令;
- ExecStop:停止服务的命令;
- PrivateTmp:本服务是否使用私有 tmp 目录,使用私有 tmp 目录能够提供一定的安全性,更多内容可以参考这里。
[Install] 部分
[Install]
WantedBy=multi-user.target
这是开机自启动的关键配置,以 nginx 为例,如果没有这一行,并且没有其他服务配置了 Requires=nginx.service 或 Wants=nginx.service,即便使用了 sudo systemctl enable nginx.service
,也无法让 nginx 开机自启动。
关于 target
target 可以认为是一组 units,启动 target 就会启动里面所有的 Unit。使用 man systemd.target
可以查看 target 的说明。
NAME
systemd.target - Target unit configuration
SYNOPSIS
target.target
DESCRIPTION
A unit configuration file whose name ends in ".target" encodes information about a target unit of systemd, which is used for grouping units and as well-known synchronization points during start-up.
This unit type has no specific options. See systemd.unit(5) for the common options of all unit configuration files. The common configuration items are configured in the generic "[Unit]" and "[Install]" sections. A separate "[Target]" section does not exist, since no target-specific options may be configured.
Target units do not offer any additional functionality on top of the generic functionality provided by units. They exist merely to group units via dependencies (useful as boot targets), and to establish standardized names for synchronization points used in dependencies between units. Among other things, target units are a more flexible replacement for SysV runlevels in the classic SysV init system. (And for compatibility reasons special target units such as runlevel3.target exist which are used by the SysV runlevel compatibility code in systemd. See systemd.special(7) for details).
...
温馨提示:反馈需要登录