Linux系统服务神器:systemctl的配置与使用

12,630 阅读6分钟

「这是我参与2022首次更文挑战的第15天,活动详情查看:2022首次更文挑战」。

前言

以前使用Ubuntu和CentOS,一般使用SysV init(就是以前使用的service)进行进程的开机自启和进程守护。

但是,现在更多地使用systemd来实现进程的管理。

Systemd

Systemd(系统管理守护进程),最开始以GNU GPL协议授权开发,现在已转为使用GNU LGPL协议。字母ddaemon的缩写

它取替并兼容传统的SysV init。事实上,CentOS和Debian,现在默认都是使用Systemd:

  • CentOS 7开始预设并使用Systemd
  • Ubuntu 15.04开始并预设使用Systemd

使用Systemd的优点:

  • 按需启动进程,减少系统资源消耗
  • 并行启动进程,提高系统启动速度

查看systemdsystemctl程序相关的目录:

whereis systemd
whereis systemctl

查看

事实上,它还是Linux的1号进程:

ps -p 1

1号进程

可以想到,优先级有多高。

Unit

Systemd引入了一个核心配置:Unit(单元配置)。事实上,Systemd管理的每个进程,都是一个Unit。相当于任务块。一个有12种模式:

  • 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:定时器

Systemctl

是不是有小伙伴问,标题是Systemctl,但是到目前为止说的都是Systemd?其实,systemctl是 Systemd 的主命令,用于操作Systemd。

接下来,我们就来试试吧。

创建配置文件

如果我们要创建一个Unit服务,我们应该如何创建配置文件呢?

我们自己配置Unit服务(后续使用Systemctl进行启动和管理),可以配置到:

  • /usr/lib/systemd/system/:推荐地址。
  • /run/systemd/system/:系统执行过程中所产生的服务脚本,这些脚本的优先级比上面的高。
  • /etc/systemd/system/:管理员根据主机系统的需求所建立的执行脚本,优先级比上面的高。

虽然,我推荐配置到/usr/lib/systemd/system/,但是还是要更加实际开发过程中遇到的情况做出改变嗷:

配置文件

比如,我编译安装了Nginx,所以我这里创建一个:

touch /usr/lib/systemd/system/nginx.service

创建成功

之后,我们要写入。

编写配置文件

使用vim进行配置文件的写入(其实刚刚不用touch创建也可以~):

vim /usr/lib/systemd/system/nginx.service

新增:

[Unit]
Description=nginx
After=network.target
  
[Service]
Type=forking
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s quit
PrivateTmp=true
  
[Install]
WantedBy=multi-user.target

添加

这些项具体什么意思呢?

这里给大家一些解释:

- 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,指定环境变量

有没有概念呢?这里再举例几个其他配置。

Demo1:Aria2交互

我们有时候会使用Aria2进行任务的下载。所以Linux服务器上会启动一个Aria2 RPC交互:

Aria2 RPC交互

这样的Aria2交互,怎么设置个开机自启或者后台运行呢?

其实用systemctl也可以,创建配置文件的方法已经在上文提及,我们看看怎么写:

[Unit]
Description=Aria2
After=network.target

[Service]
User=root
Type=simple
ExecStart=/etc/aria2/aria2c --conf-path=/etc/aria2/aria2.conf

[Install]
WantedBy=multi-user.target

其中:

  • After:在网络启动后运行。
  • Type:使用simple,即使ExecStart启动不成功,Unit任务也会继续执行。
  • ExecStart:Unit的主进程,相当于入口。

Demo2:PHP-FPM

PHP-FPM也会使用Systemctl来写进程守护。话不多说:

[Unit]
Description=php-fpm
After=network.target
  
[Service]
Type=forking
ExecStart=/usr/local/php7/sbin/php-fpm
PrivateTmp=true
  
[Install]
WantedBy=multi-user.target

其中:

  • Type:使用forkingExecStart= 进程将会在启动过程中使用 fork() 系统调用。

Demo3:NPM Start

当然,有些用户会用systemctl去守护NPM进程,这里也举例:

[Unit]
Description=NodeServer

[Service]
ExecStart=/usr/bin/node /root/myApplication/NodeServer/app.js
Restart=always
Environment=PATH=/usr/bin:/usr/local/bin:/usr/local/node/bin
Environment=NODE_ENV=production
WorkingDirectory=/root/myApplication/NodeServer/

[Install]
WantedBy=multi-user.target 

现在,我们就来试试启动和维护。

使用Systemctl

重载配置

我们编写了配置文件,需要让配置文件生效。很简单,只需要使用命令:

systemctl daemon-reload

重载配置

这样systemctl重新载入配置文件就好了。

启动服务

我们使用systemctl启动服务也很简单,比如::

# 启动刚刚配置的Nginx服务
systemctl start nginx
# 启动刚刚配置的Aria2服务
systemctl start aria2

启动服务

可以看到,Aria2没什么问题,但是Nginx启动失败了。我们可以按提示,查看详情:

查看详情

这样就可以知道为什么错了,主要是我Nginx编译设置问题,我调整一下。

启动成功

Nginx这种服务,设置了ExecReload,还可以使用relaod重载配置:

systemctl reload nginx

reload服务

停止服务也很简单:stop

systemctl stop aria2
systemctl stop nginx

查看状态

我们想看我们启动的单元状态也很简单,使用status命令即可:

systemctl status aria2
systemctl status nginx

查看状态

类似于看终端前台输出。

开机自启

使用systemctl设置开机自启很简单:

systemctl enable aria2
systemctl enable nginx

设置开机自启

查看Unit单元是否设置了开机自启:

systemctl is-enable aria2

查看是否开机自启 当然,取消开机自启就是:

systemctl disable aria2
systemctl disable nginx

取消开机自启

其他

以上是systemctl的常用命令,这里讲一下不常用,但是也很实用的。

查看Unit服务

如果你想查看所有Unit服务,用Systemctl可以这样:

systemctl list-units

当然,可以省略为:

systemctl

查看所有Unit服务

当然,你可以配合grep命令操作:

systemctl | grep -E 'UNIT|aria2'

配合grep命令

END

到此,就是本次Linux命令分享、分析的全部内容啦。systemctl还真是个神器。毕竟是1号进程,哈哈,够强劲。

下次分享什么内容呢?