在CentOS 7及之后的版本中,systemd已经成为默认的系统和服务管理器,而systemctl则是与systemd交互的主要命令行工具。它承担了过去service、chkconfig、init等命令的大部分职责,并且引入了unit(单元)的概念来统一管理服务、挂载点、套接字、定时器等系统资源。对于刚接触CentOS新版本的用户来说,掌握systemctl是高效管理系统服务的第一步。

与传统的SysV init脚本相比,systemd最大的优势在于并行启动。在旧的init系统中,服务按照/etc/rc.d/rcN.d中的数字顺序依次启动,串行执行往往导致开机速度缓慢。而systemd通过解析unit文件中的依赖关系,能够并行启动没有依赖冲突的服务,显著缩短系统启动时间。systemctl命令正是管理这些unit的前端工具,使用它无需直接编辑脚本,也无需记忆复杂的启动顺序。
systemctl基础操作:启动、停止、重启与重载
最常用的systemctl操作莫过于对服务的启动、停止、重启和重载。命令格式非常直观,通常为systemctl 动作 服务名。例如要启动Nginx服务,执行systemctl start nginx;停止服务则用systemctl stop nginx。这两个命令分别是向systemd发送SIGTERM和SIGKILL信号,但systemd会负责追踪进程状态,确保服务彻底停止后再返回。
重启服务使用systemctl restart nginx,它会先停止再启动,等效于连续执行stop和start。但有些服务支持reload操作,例如修改了Nginx的配置文件后,不希望中断现有连接,就可以使用systemctl reload nginx,该命令会向服务进程发送SIGHUP信号,让服务重新加载配置而不完全重启。如果某个服务不支持reload,执行该命令会报错,此时只能使用restart。下面是一组常见的操作示例:
# 启动服务 systemctl start nginx # 停止服务 systemctl stop nginx # 重启服务 systemctl restart nginx # 重新加载配置(如果服务支持) systemctl reload nginx # 查看服务是否处于活动状态 systemctl is-active nginx # 查看服务是否被设置为开机启动 systemctl is-enabled nginx
有些服务在运行过程中可能会因为配置文件错误而启动失败,这时systemctl restart会返回非零退出码,并且不会启动服务。为了快速判断问题原因,通常会结合systemctl status和日志命令一起使用,这一点会在下一节详细介绍。
查看服务状态与理解输出信息
systemctl status 服务名是运维人员最频繁使用的命令之一,它展示的信息远比传统的service nginx status丰富。执行该命令后,典型的输出包含服务名称、加载状态、活动状态、主进程ID、任务数以及最近几条日志。例如查看sshd服务的状态:
[admin@centos7 ~]$ systemctl status sshd
● sshd.service - OpenSSH server daemon
Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2024-03-01 08:10:20 CST; 2h 15min ago
Docs: man:sshd(8)
man:sshd_config(5)
Main PID: 1032 (sshd)
Tasks: 1
Memory: 1.2M
CGroup: /system.slice/sshd.service
└─1032 /usr/sbin/sshd -D
输出中的Loaded行表明unit文件的加载路径以及是否被设置为开机自启(enabled表示已启用)。Active行是核心状态,active (running)表示服务正在正常运行,如果服务启动失败则会显示failed (Result: exit-code)之类的信息。后面的时间戳表示服务自何时开始运行,以及已经持续运行了多久。Main PID是服务主进程的ID,CGroup则展示了进程在控制组中的层级关系,方便查看服务派生的子进程。需要注意的是,这个状态输出中的●符号在一些终端可能显示为其他字符,但不会影响信息读取。
除了基本的status,systemctl还提供了列表查看功能。systemctl list-units --type=service可以列出所有已加载的service单元及其状态,systemctl list-unit-files --type=service则显示所有已安装的service单元文件,不论它们当前是否处于活动状态。如果只想查看失败的服务,可以用systemctl --failed,该命令会列出所有启动失败或运行异常的单位,是快速定位系统健康问题的好帮手。
管理服务开机自启与运行级别
过去在CentOS 6中使用chkconfig命令设置服务开机自启,如今systemctl将这一功能合并进了enable和disable子命令。执行systemctl enable nginx会创建符号链接,将unit文件链接到对应的target目录下,从而在系统启动时自动加载该服务。相反,systemctl disable nginx会移除这些符号链接。可以使用systemctl is-enabled nginx查看服务当前的开机启动状态,如果输出enabled表示已启用,disabled表示未启用,static表示该服务无法单独启用或禁用,通常是因为它由其他服务依赖启动。
运行级别(runlevel)在systemd中被替换为target的概念。CentOS 7默认使用multi-user.target(相当于运行级别3),图形界面则对应graphical.target(相当于运行级别5)。切换运行级别使用systemctl isolate命令,例如systemctl isolate multi-user.target切到多用户文本模式,systemctl isolate graphical.target切到图形界面。设置默认启动级别则使用systemctl set-default,例如systemctl set-default graphical.target。这些操作替换了旧版中的init 3、init 5以及编辑/etc/inittab文件的方式。
# 设置Nginx开机自启 systemctl enable nginx # 取消Nginx开机自启 systemctl disable nginx # 查看默认启动目标 systemctl get-default # 设置默认启动为图形界面 systemctl set-default graphical.target # 临时切换到多用户模式(不重启) systemctl isolate multi-user.target
需要注意的是,enable和disable只影响开机启动,不会立即启动或停止服务。如果想同时启动并设置开机自启,可以使用systemctl enable --now nginx,这个选项在较新版本的systemd中支持,等效于先执行enable再执行start。同理,--now也可以与disable搭配,实现立即停止并取消开机自启。
深入unit文件:自定义服务与依赖管理
systemd的强大之处在于可以通过unit文件灵活定义服务。unit文件存放在三个目录中:/usr/lib/systemd/system/存放发行版自带的软件包unit,/etc/systemd/system/存放系统管理员自定义的unit,/run/systemd/system/存放运行时生成的unit。它们的优先级从高到低依次为/etc、/run、/usr。管理员通常将自己的服务定义放在/etc/systemd/system/目录下,并且可以使用systemctl edit命令创建或修改unit文件,推荐使用systemctl edit --full来创建完整的unit文件,避免仅创建override片段带来的疑惑。
一个典型的自定义service单元文件可能如下所示,我们需要创建一个名为/etc/systemd/system/myapp.service的文件,内容如下:
[Unit] Description=My Custom Application After=network.target [Service] Type=simple User=myapp WorkingDirectory=/opt/myapp ExecStart=/usr/bin/python3 /opt/myapp/app.py Restart=on-failure RestartSec=5s Environment=MYAPP_ENV=production [Install] WantedBy=multi-user.target
在单元文件中,[Unit]段定义了元数据和依赖关系,After=network.target表示该服务在网络初始化完成后再启动;[Service]段是核心,Type=simple表示主进程由ExecStart启动后不会fork,systemd会直接跟踪该进程;ExecStart写明启动命令;Restart=on-failure表示服务异常退出时自动重启,但被手动stop的情况不重启。最后一个[Install]段指定了该服务应该被加入哪个target的WantedBy列表中,这样执行systemctl enable myapp时会在multi-user.target.wants目录创建软链接,从而实现开机自启。
创建完成后,需要执行systemctl daemon-reload让systemd重新加载所有unit文件,然后就可以使用systemctl start myapp启动服务了。如果启动失败,可以使用systemctl status myapp和journalctl -u myapp查看详细日志定位问题。journalctl是systemd的日志查看工具,配合-u参数可以过滤指定服务的日志,例如journalctl -u myapp -f可以实时跟踪服务日志,对于调试极为方便。另外journalctl -p err可以只看错误级别的日志,journalctl --since today可以限制时间范围。
掌握这些systemctl与journalctl的组合用法后,处理服务故障会变得轻松很多。无论是对现有服务的管理,还是自建服务的部署,都能脱离对旧式脚本的依赖,真正发挥systemd带来的管理优势。后续建议多实践systemctl cat命令查看已有服务的unit文件内容,从中学习官方软件包的编写风格,快速提升配置水平。

