简介
Linux 系统的 init 进程经历了两次重大的演进,传统的 sysvinit 已经逐渐淡出历史舞台,新的 UpStart 和 systemd 各有特点,越来越多的 Linux 发行版采纳了 systemd
特性:
- 更快的启动速度
- Systemd 提供了比 UpStart 更激进的并行启动能力,采用了 socket / D-Bus activation 等技术启动服务
- 为了减少系统启动时间,systemd 的目标是
- 尽可能启动更少的进程
- 尽可能将更多进程并行启动
- 自带日志服务
- systemd 自带日志服务 journald,该日志服务的设计初衷是克服现有的 syslog 服务的缺点。
- syslog 不安全,并且数据没有严格的格式。
- Systemd Journal 用二进制格式保存所有日志信息,用户使用 journalctl 命令来查看日志信息
- Systemd Journal 的主要优点如下
- 零维护:日志是除错和监控系统的核心功能,因此它自己不能再产生问题。举例说,自动管理磁盘空间,避免由于日志的不断产生而将磁盘空间耗尽。
- 最小资源占用:日志 数据文件需要较小。
编写服务
编写一个systemctl服务的步骤如下:
- 创建一个新的服务单元文件,通常位于/etc/systemd/system/目录下。文件名应该以.service结尾,例如my-service.service。
- 编辑服务单元文件,添加以下内容:
[Unit]
Description=我的自定义服务
After=network.target #指定了服务启动顺序,在network.target服务启动后,再启动当前服务
[Service]
# Type:字段定义启动类型,可以设置的值如下:
# simple(默认值):ExecStart 字段启动的进程为主进程,即直接启动服务进程。
# forking:ExecStart 字段将以 fork() 方式启动,此时父进程将会退出,子进程将成为主进程(例如用 shell 脚本启动服务进程)。
Type=simple
User=USER # 设置服务运行的用户
Group=USER # 设置服务运行的用户组
WorkingDirectory=/PATH # 设置服务运行的路径(cwd)
ExecStart=/usr/bin/my-service-command # 服务启动命令,命令需要绝对路径
Restart=on-failure
[Install]
# systemd提供了一些默认的目标(target),如multi-user.target、graphical.target等
WantedBy=multi-user.target
其中,
- [Unit]:设置启动顺序
- Description字段描述了服务的功能,
- After字段指定了服务启动顺序,在network.target服务启动后,再启动当前服务
- [Service]:设置启动行为
- Type字段定义了服务的类型,
- User字段指定了运行服务的用户,
- ExecStart字段指定了启动服务的命令,
- Restart字段定义了服务失败时的重启策略,
- [Install]:服务安装到哪个场景:命令行还是图形界面
- WantedBy字段指定了服务所属的目标。
- 保存并关闭服务单元文件。
- 重新加载systemd配置,使新的服务生效:
sudo systemctl daemon-reload
- 启动新创建的服务:
sudo systemctl start my-service.service
- 检查服务的状态:
sudo systemctl status my-service.service
- 如果需要,可以将服务设置为开机自启动:
sudo systemctl enable my-service.service
- 如果需要停止或禁用服务,可以使用以下命令:
sudo systemctl stop my-service.service
sudo systemctl disable my-service.service
常用命令
启动/停止/重启服务
sudo systemctl start serviceName
sudo systemctl stop serviceName
sudo systemctl restart serviceName
状态查询
# 列出所有正在运行的服务
systemctl list-units --type=service --state=active
# 状态查询
systemctl status serviceName
# 检查服务是否启用
systemctl is-enabled serviceName
查默认日志
# 查看服务日志,查看名为 serviceName 的服务的日志,以检查启动问题
sudo journalctl -u serviceName
查更详细日志
编辑服务配置文件
sudo systemctl edit serviceName
[Service]
Environment=SYSTEMD_LOG_LEVEL=debug
然后重新加载 systemd 并启动服务,以获得详细的启动日志:
sudo systemctl daemon-reload
sudo systemctl restart serviceName
常见问题
service文件放哪个目录?
- /etc/systemd/system/
- 这个目录专门用于存放用户自定义的服务单元文件
- /usr/lib/systemd/system/
- 这个目录通常包含由软件包安装的服务单元文件。不过,用户创建的服务单元文件应该放在/etc/systemd/system/目录下,以避免在升级系统时被覆盖。
启动顺序一般After哪个?
- 看具体情况,一般After=network.target 可以满足大部分场景(服务在网络服务正常后,再启动当前服务)