什么是系统服务(service)
简单理解就是开机自启动的程序或者脚本, 会常驻在系统的内存中.
对于现在的大部分的 linux 发行版, 系统服务通常使用 systemd 进行管理.
三种配置文件
- 系统:
- dir:
/usr/lib/systemd/system/ - 这里存放着系统自带的服务单元, 如 apt. 一般不建议随便乱动这里的服务, 除非你知道自己在干什么.
- 运行时:
- dir:
/run/systemd/system/ - 临时服务, 一般可其他服务或者用户行为启动的临时服务. 在系统重启后清空
- 管理员:
- dir:
/etc/systemd/system/ - 用户自定义的服务, 管理员系统服务优先级高于系统服务, 意味着它会覆盖系统中相同的服务.
如果我们想添加自己的系统服务, 建议都放在管理员服务目录下.
.service 文件
为什么要定义这种文件格式
- 用于描述该服务的内容, 配置, 策略等
- 可以使用
systemctl命令来管理服务. - 统一服务的管理.
核心结构
Unit
用于定义服务的元信息(meta data)和依赖.
[Unit]
Description=My Service
Documentation=https://example.org/docs/my-service
After=network.target #这里需要定义这个服务在哪个服务之后启动
Wants=network.target #弱依赖
Requires=network.target #强依赖
常见的系统服务目标(可以在 After 中使用):
basic.target: 基础系统初始化完成network.target: 网络已启动multi-user.target: 多用户模式(常规启动模式)graphical.target: 图形界面模式remote-fs.target: 远程文件系统已挂载syslog.target: 系统日志服务time-sync.target: 系统时间已同步nss-lookup.target: 网络名称解析服务sound.target: 声音系统bluetooth.target: 蓝牙服务
也可以直接指定其他具体的服务,例如:
After=mysql.service redis.service
服务依赖关系选项:
Requires=: 强依赖,如果依赖的服务启动失败,该服务也会失败Wants=: 弱依赖,依赖服务的启动状态不影响本服务BindsTo=: 绑定依赖,依赖服务停止时,该服务也会停止PartOf=: 部分依赖,依赖服务停止或重启时,该服务也会停止或重启Conflicts=: 冲突依赖,与指定服务冲突,不能同时运行Before=: 在指定服务之前启动After=: 在指定服务之后启动
示例:
Wants=redis.service
After=network.target redis.service
Conflicts=apache2.service
Service
定义服务的行为
[Service]
Type = simple
ExecStart = /usr/bin/redis-server /etc/redis/redis.conf
Restart = always
User = redis
Group = redis
Environment = e.g. PATH=/usr/bin
WorkingDirectory = /etc/redis
Service 块的主要配置项:
Type: 服务的启动类型
-
simple: 默认值,ExecStart 启动的进~程为主进程,启动后会持续运行。适用于持续运行的服务,如 web 服务器、数据库等。 示例:[Service] Type=simple ExecStart=/usr/bin/nginx -g 'daemon off;' -
oneshot: 一次性进程,执行完就退出。适用于只需要执行一次的任务,如系统初始化脚本。通常需要配合RemainAfterExit=yes使用,表示进程退出后服务仍然处于活动状态。比如我要执行一个脚本, 那么我可以通过关闭这个服务来关闭这个脚本. 示例:[Service] Type=oneshot RemainAfterExit=yes ExecStart=/usr/local/bin/init-script.sh -
forking: 服务会 fork,父进程退出后服务启动成功 -
notify: 服务启动完成后会通知 systemd -
dbus: 通过 D-Bus 启动 -
idle: 等待其他任务处理完成后才启动~
-
ExecStart: 启动服务时执行的命令 -
ExecStop: 停止服务时执行的命令 -
ExecReload: 重载服务时执行的命令 -
Restart: 服务重启策略
no: 不自动重启always: 总是重启on-success: 正常退出时重启on-failure: 非正常退出时重启on-abnormal: 被信号终止或超时时重启on-abort: 收到未处理信号退出时重启
- 权限相关:
User: 以某个用户身份运行Group: 以某个用户组运行Nice: 进程优先级,数值范围为 -20 到 19
- 环境相关:
Environment: 设置环境变量EnvironmentFile: 环境变量配置文件WorkingDirectory: 工作目录
-
资源限制:
-
CPU 相关限制:
CPUQuota: CPU 时间配额限制,以百分比表示。100% 表示一个逻辑处理器的全部时间。例如:CPUQuota=100%: 限制使用一个逻辑处理器的全部时间CPUWeight: CPU 权重,范围 1-10000,默认 100CPUAffinity: 指定进程可以运行在哪些 CPU 核心上,例如CPUAffinity=0,1,2表示只能在前三个核心上运行
MemoryLimit: 内存使用限制,支持单位 K、M、G、T,如MemoryLimit=1GLimitNOFILE: 文件描述符限制,如LimitNOFILE=65535LimitNPROC: 进程数限制,如LimitNPROC=4096TasksMax: 任务数限制,如TasksMax=100IOWeight: IO 权重,范围 1-10000,默认 100BlockIOWeight: 块设备 IO 权重,范围 10-1000DeviceAllow: 设备访问控制,如DeviceAllow=/dev/sda r表示只读访问
示例:
[Service]
CPUQuota=200%
CPUWeight=500
CPUAffinity=0,1
MemoryLimit=500M
LimitNOFILE=65535
TasksMax=200
IOWeight=500
Install
定义如何将服务安装到系统,主要用于配置服务的自启动行为。常用配置项:
WantedBy: 服务被启用时创建的符号链接的目标。最常用的值是:multi-user.target: 多用户命令行模式graphical.target: 图形界面模式
RequiredBy: 与 WantedBy 类似,但创建强依赖关系Also: 同时启用或停用的其他单元Alias: 为服务创建别名
示例:
[Install]
WantedBy=multi-user.target
Alias=myapp.service
Also=myapp-logger.service
服务安装相关命令:
systemctl enable <服务名>: 启用服务(开机自启)systemctl disable <服务名>: 停用服务systemctl is-enabled <服务名>: 检查服务是否启用
我的 mc 服务器系统服务实例
[Unit]
Description=Minecraft Server
After=network.target
[Service]
Type=oneshot
User=m
CPUQuota=10000%
WorkingDirectory=/home/m/桌面/mc_server
ExecStart=/bin/sh run.sh
ExecStop=/bin/sh run.sh stop
RemainAfterExit=yes
Restart=on-failure
[Install]
WantedBy=multi-user.target
服务操作 | Service Operation
- 启动服务
systemctl start mc.service - 开机启动服务
systemctl enable mc.service - 查看服务状态
systemctl status mc.service - 停止服务
systemctl stop mc.service