Systemd其实是Linux系统用来管理系统的一个程序,用来代替原来的init进程(用来管理启动系统其它的服务进程),现在很多Linux发行版都已经自带Systemd程序了。
Systemd 的优点是功能强大,使用方便,缺点是体系庞大,非常复杂。Systemd与操作系统的其他部分强耦合,违反”keep simple, keep stupid”的Unix 哲学。
Systemd 架构图如下:
- systemctl命令组成
1. Unit
systemctl命令是Systemd中最重要的一个命令,用于对服务进行启动,停止等操作,在Systemd中有Unit的概念,每个进程都是一个Unit,总共有十二种Unit类型。
Service unit,系统服务 Target unit,多个 Unit 构成的一个组 Device Unit,硬件设备 Mount Unit,文件系统的挂载点 Automount Unit,自动挂载点 Path Unit,文件或路径 Scope Unit,不是由 Systemd 启动的外部进程 Slice Unit,进程组 Snapshot Unit,Systemd 快照,可以切回某个快照 Socket Unit,进程间通信的 socket Swap Unit,swap 文件 Timer Unit,定时器
2. 常用命令
# 列出正在运行的Unit systemctl list-units,可以直接使用systemctl # 列出所有Unit,包括没有找到配置文件的或者启动失败的 systemctl list-units --all # 列出所有没有运行的 Unit systemctl list-units --all --state=inactive # 列出所有加载失败的 Unit systemctl list-units --failed # 列出所有正在运行的、类型为service的Unit systemctl list-units --type=service # 显示某个 Unit 是否正在运行 systemctl is-active application.service # 显示某个 Unit 是否处于启动失败状态 systemctl is-failed application.service # 显示某个 Unit 服务是否建立了启动链接 systemctl is-enabled application.service # 立即启动一个服务 sudo systemctl start apache.service # 立即停止一个服务 sudo systemctl stop apache.service # 重启一个服务 sudo systemctl restart apache.service # 重新加载一个服务的配置文件 sudo systemctl reload apache.service # 重载所有修改过的配置文件 sudo systemctl daemon-reload
3)systemctl中Unit的配置文件
Systemd默认从目录/etc/systemd/system/读取配置文件。但是里面存放的大部分文件都是符号链接,指向目录/usr/lib/systemd/system/,真正的配置文件存放在那个目录。
可以使用```systemctl cat```命令来查看服务的配置文件,下面是Mysql的配置文件,很多软件已经支持Systemd程序了,安装的时候会自动配置它的Unit配置文件,例如Mysql和Nginx等等。 systemctl cat mysqld # /usr/lib/systemd/system/mysqld.service [Unit] Description=MySQL Server Documentation=man:mysqld(8) Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html After=network.target After=syslog.target [Install] WantedBy=multi-user.target [Service] User=mysql Group=mysql Type=forking PIDFile=/var/run/mysqld/mysqld.pid # Disable service start and stop timeout logic of systemd for mysqld service. TimeoutSec=0 # Execute pre and post scripts as root PermissionsStartOnly=true # Needed to create system tables ExecStartPre=/usr/bin/mysqld_pre_systemd # Start main service ExecStart=/usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid $MYSQLD_OPTS # Use this to switch malloc implementation EnvironmentFile=-/etc/sysconfig/mysql # Sets open_files_limit LimitNOFILE = 5000 Restart=on-failure RestartPreventExitStatus=1 PrivateTmp=false
4)Unit配置文件的含义解释:
可以看到Unit配置文件有很多标签,不同的标签都代表了不同的意思,这里只列出部分介绍,可以去官网查看Unit配置文件文档介绍,https://www.freedesktop.org/software/systemd/man/systemd.unit.html。 - Unit - Description,服务的描述 - Documentation,文档介绍 - After,该服务要在什么服务启动之后启动,比如Mysql需要在network和syslog启动之后再启动 - Install - WantedBy,值是一个或多个Target,当前Unit激活时(enable)符号链接会放入/etc/systemd/system目录下面以Target名+.wants后缀构成的子目录中 - RequiredBy,它的值是一个或多个Target,当前Unit激活(enable)时,符号链接会放入/etc/systemd/system目录下面以Target名+.required后缀构成的子目录中 - Alias,当前Unit可用于启动的别名 - Also,当前Unit激活(enable)时,会被同时激活的其他Unit - Service - Type,定义启动时的进程行为。它有以下几种值。 - Type=simple,默认值,执行ExecStart指定的命令,启动主进程 - Type=forking,以 fork 方式从父进程创建子进程,创建后父进程会立即退出 - Type=oneshot,一次性进程,Systemd 会等当前服务退出,再继续往下执行 - Type=dbus,当前服务通过D-Bus启动 - Type=notify,当前服务启动完毕,会通知Systemd,再继续往下执行 - Type=idle,若有其他任务执行完毕,当前服务才会运行 - ExecStart,启动当前服务的命令 - ExecStartPre,启动当前服务之前执行的命令 - ExecStartPost,启动当前服务之后执行的命令 - ExecReload,重启当前服务时执行的命令 - ExecStop,停止当前服务时执行的命令 - ExecStopPost,停止当其服务之后执行的命令 - RestartSec,自动重启当前服务间隔的秒数 - Restart,定义何种情况 Systemd 会自动重启当前服务,可能的值包括always(总是重启)、on-success、on-failure、on-abnormal、on-abort、on-watchdog - TimeoutSec,定义 Systemd 停止当前服务之前等待的秒数 - Environment,指定环境变量
5)查看Unit启动日志
# 查看所有日志(默认情况下 ,只保存本次启动的日志) journalctl # 查看指定时间的日志 journalctl --since="2012-10-30 18:17:16" journalctl --since "20 min ago" journalctl --since yesterday journalctl --since "2015-01-10" --until "2015-01-11 03:00" journalctl --since 09:00 --until "1 hour ago" # 显示尾部的最新10行日志 journalctl -n # 显示尾部指定行数的日志 journalctl -n 20 # 实时滚动显示最新日志 journalctl -f # 查看指定服务的日志 journalctl /usr/lib/systemd/systemd # 查看指定进程的日志 journalctl _PID=1 # 查看某个路径的脚本的日志 journalctl /usr/bin/bash # 查看指定用户的日志 journalctl _UID=33 --since today # 查看某个 Unit 的日志 journalctl -u nginx.service journalctl -u nginx.service --since today # 实时滚动显示某个 Unit 的最新日志 journalctl -u nginx.service -f # 合并显示多个 Unit 的日志 $ journalctl -u nginx.service -u php-fpm.service --since today
- 常用的自定义systemd服务
1)自动挂载usb设备
#如果挂载点为/mnt/aaa/bbb,那么systemd名为mnt-aaa-bbb.mount cat<<EOF >>/etc/systemd/system/mnt-backups.mount [Unit] Description=Mount System Backups Directory [Mount] What=/dev/disk/by-uuid/86fef3b2-bdc9-47fa-bbb1-4e528a89d222 Where=/mnt/backups Type=ext4 Options=defaults [Install] WantedBy=multi-user.target EOF systemctl daemon-reload systemctl start mnt-backups.mount systemctl enable mnt-backups.mount
2)自动挂载NFS文件系统
#qt.mount需要和挂载的本地路径/qt一致 cat << EOF >/etc/systemd/system/qt.mount [Unit] Description=AUTO Mount NFS After=network.target nss-lookup.target [Mount] What=10.10.20.6:/volume1/qt Where=/qt Type=nfs Options=rw,vers=4 [Install] WantedBy=multi-user.target EOF #启动挂载 systemctl start qt.mount #停止挂载 systemctl stop qt.mount
3)openai的服务
cat << EOF >/usr/lib/systemd/system/openai.service [Unit] Description=openai After=network.target nss-lookup.target [Service] Type=simple Restart=always User=root Group=root WorkingDirectory=/root/chatbot-ui ExecStart=/usr/bin/npm run dev [Install] WantedBy=multi-user.target EOF
- 小结
systemctl配置较为复杂,但是当配置好后,能够方便的管理相关的服务,通过现有的工具查看日志和分析问题。
参考资料:
- https://segmentfault.com/a/1190000023029058
- https://foxi.buduanwang.vip/linux/2115.html/
- https://blog.csdn.net/qq_44397993/article/details/130044886
- https://serverfault.com/questions/1018676/how-to-configure-systemd-service-unit-to-start-node-app-with-npm-start-instead
- https://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-commands.html