• Ukieweb

    佳的博客

    曾梦想仗剑天涯,后来工作忙没去。

Centos 7 systemctl(systemd)服务日志管理 新增 service 服务 开机启动

1. System V 和 Systemd 介绍

在 CentOS 7 之前,系统以 System V  Init Script 来作为系统管理器。System V 有一个致命的缺点就是过度依赖于脚本来实现服务管理,从而导致服务几乎没办法并行启动,最终导致系统启动效率较为低下。

从 CentOS 7 开始,Systemd 成为新的系统管理器。我认为它最大的优点就是支持进服务并行启动,从而使效率大大提高;同时它还具有日志管理、快照备份与恢复、挂载点管理等多种实用功能,功能甩 System V 几条街!

而且 systemd 进程的 PID 是 1 ,也就是说 Systemd 掌管着一切进程!当然了 Systemd 是向下兼容 System V 的。

以下只介绍 Systemd 的服务启动项和日志管理这三项功能,其他功能不涉及。

说明

  1. 下文提到的服务项名称后面的 .service 可以省略不写,系统会自动补全。

  2. Systemd 不仅仅管理系统的服务项,还能管理着挂载点、套接字等。每一个 Systemd 管理项称为 unit,unit可以有很多类型。本文仅介绍 .service 类型和 .target 的 unit 。

  3. 本文适用于所有使用 Systemd 的操作系统,不局限于 CentOS 7。

服务的状态一览

  • active (running): 正有一只或多只程序正在系统中执行的意思

  • active (exited): 仅执行一次就正常结束的服务,目前并没有任何程序在系统中执行。 举例来说,开机或者 是挂载时才会进行一次的 quotaon 功能,就是这种模式! 

  • active (waiting): 正在执行当中,不过还再等待其他的事件才能继续处理。

  • inactive: 这个服务目前没有运作的意思。

  • enabled: 这个 daemon 将在开机时被执行

  • disabled: 这个 daemon 在开机时不会被执行

  • static: 这个 daemon 不可以自己启动 (enable 不可),不过可能会被其他的 enabled 的服务来唤醒 (相依属性的服务)

  • mask: 这个 daemon 无论如何都无法被启动!因为已经被强制注销 (非删除)。可透过 systemctl unmask 方 式改回原本状态

2.服务、系统状态的查看

#查看系统所有 安装 的服务项
systemctl list-unit-files --type=service

# 查看系统所有 运行 的服务项
# 如果看到某个服务项前面有一个红点,说明该服务存在问题,请进行排查。
systemctl list-units --type=service

# 查看系统所有 开机自启动 的服务项
systemctl list-unit-files --type=service | grep enabled

# 查看服务项的 依赖关系
systemctl list-dependencies <服务项名称>

# 查看出错的服务
systemctl list-units --type=service --state=failed

# 清除服务项的错误状态
systemctl reset-failed <服务项名称>

# 查看系统启动耗时
systemd-analyze

# 查看各项服务启动耗时
systemd-analyze blame | grep .service

3.服务的管理

# 启动服务
systemctl start <服务项名称>

# 停止服务
systemctl stop <服务项名称>

# 重启服务
systemctl restart <服务项名称>

# 查看指定服务项状态
# 执行命令之后,系统会显示该服务项的状态、是否已激活、描述以及最后十条日志。
# 如果服务项前面有一个红点,说明该服务存在问题,请根据日志进行排查。
systemctl status <服务项名称>

# 重新读取配置文件
# 如果该服务不能重启,但又必须使用新的配置,这条命令会很有用。
systemctl reload <服务项名称>

# 使服务开机自启动
systemctl enable <服务项名称>

# 使服务不要开机自启动
systemctl disable <服务项名称>

# 禁用服务
# 这可以防止服务被其他服务间接启动,也无法通过 start 或 restart 命令来启动服务。
systemctl mask <服务项名称>

# 启用服务
# 仅针对于已禁用的服务。
systemctl unmask <服务项名称>

# 重新读取所有服务项
# 修改、添加、删除服务项之后需要执行以下命令。
systemctl daemon-reload

4.简单服务文件的创建

4.1 服务文件的位置

我们自己建立的服务文件直接放在 /etc/systemd/system/ 里面就好了。服务文件要使用 .service 后缀名。

如需修改软件包或系统自带的服务文件,请先将原版服务文件从 /lib/systemd/system/ 拷贝到 /etc/systemd/system/ 再进行修改。

4.2 服务文件的模版

以下是最简单的配置模版,直接根据提示或注释修改参数值,然后去掉所有注释即可。

[Unit]
Description= elasticsearch server
After=network.target

[Service]
Type=forking
User=es
ExecStart=/opt/sky/elasticsearch-7.6.2/bin/elasticsearch -d

[Install]
WantedBy=multi-user.target

 创建服务文件之后,最好执行一下 systemctl daemon-reload 再启用。

AFTER 常用服务:

  • 网络就绪: network.target

  • systemctl list-unit-files --type=target    //列出系统中所有的target

4.3 service 的组成

service文件中包含三个部分,分别是:[Unit]、[Service]、[Install]

[Unit] 部分

  • Description一段描述这个 Unit 文件的文字,通常只是简短的一句话。

  • Documentation指定服务的文档,可以是一个或多个文档的 URL 路径

  • Requires依赖的其他 Unit 列表列在其中的 Unit 模块会在这个服务启动的同时被启动,并且如果其中有任意一个服务启动失败这个服务也会被终止

  • After与 Requires 相似,但会在后面列出的所有模块全部启动完成以后,才会启动当前的服务

  • Before与 After 相反,在启动指定的任一个模块之前,都会首先确保当前服务已经运行。

  • Wants与 Requires 相似,但只是在被配置的这个 Unit 启动时,触发启动列出的每个 Unit 模块,而不去考虑这些模块启动是否成功

  • Conflicts与这个模块有冲突的模块,如果列出模块中有已经在运行的,这个服务就不能启动,反之亦然。

  • OnFailure当这个模块启动失败时,就自动启动列出的每个 unit 模块

[Service] 部分

  • Type:服务常见的类型:simple ;forking; oneshot;notify 更多的 type 见下面讲解

  • Environment为服务添加环境变量

  • EnvironmentFile指定加载一个包含服务所需的环境变量列表的文件,文件中的每一行都是一个环境变量的定义。

  • ExecStart这个参数是几乎每个 .service 文件都会有的,指定服务启动的主要命令,在每个配置文件中只能使用一次。需要使用绝对路径

  • ExecStartPre指定在启动执行 ExecStart 的命令前的准备工作,可以有多个,所有命令会按照文件中书写的顺序依次被执行

  • ExecStartPost指定在启动执行 ExecStart 的命令后的收尾工作,也可以有多个。

  • ExecStop停止服务所需要执行的主要命令。需要使用绝对路径

  • ExecStopPost指定在 ExecStop 命令执行后的收尾工作,也可以有多个。

  • ExecReload重新加载服务所需执行的主要命令。需要使用绝对路径

  • Restart这个值用于指定在什么情况下需要重启服务进程。常用的值有noon-successon-failureon-abnormalon-abort always默认值为 no,即不会自动重启服务。这些不同的值分别表示了在哪些情况下,服务会被重新启动

  • RestartSec如果服务需要被重启,这个参数的值为服务被重启前的等待秒数

  • Nice服务的进程优先级,值越小优先级越高,默认为 0。-20 为最高优先级,19 为最低优先级。

  • WorkingDirectory指定服务的工作目录

  • RootDirectory指定服务进程的根目录( / 目录),如果配置了这个参数后,服务将无法访问指定目录以外的任何文件

  • User指定运行服务的用户,会影响服务对本地文件系统的访问权限。

  • Group指定运行服务的用户组,会影响服务对本地文件系统的访问权限。

  • PrivateTmp是否给服务分配独立的临时空间(true/false)

  • PIDFile 该服务PID文件的路径(一般位于 /run/ 目录下)。 强烈建议在 Type=forking 的情况下明确设置此选项。 如果设为相对路径,那么表示相对于 /run/ 目录。 systemd 将会在此服务启动完成之后,从此文件中读取主服务进程的PID 。 systemd 不会写入此文件,但会在此服务停止后删除它(若仍然存在)。

[Install] 部分

  • WantedBy=multi-user.target   表明当系统以多用户方式(默认的运行级别)启动时,这个服务查看会被执行

  • RequiredBy 和前面的 Requires 作用相似,只是后面列出的不是服务所依赖的模块,而是依赖当前服务的模块。

  • Aaso当这个服务被 enable/disable 时,将自动 enable/disable 后面列出的每个模块。


service 部分中的 type 类型 讲解
  • simple

当设置了 ExecStart= 、 但是没有设置 Type= 与 BusName= 时,这是默认值.

表示 ExecStart= 的命令会在 当前 shell执行,可以理解为在前台运行。如果命令有 --daemon 参数的话需要加上,不然不会退出。

在创建主服务进程之后、执行主服务进程之前,即可启动后继单元, 从而加快了后继单元的启动速度。 这就意味着对于 simple 类型的服务来说,即使不能成功调用主服务进程(例如 User= 不存在、或者二进制可执行文件不存在), systemctl start 也仍然会执行成功

  • exec

exec 与 simple 类似,但对于 exec 类型的服务来说, 如果不能成功调用主服务进程(例如 User= 不存在、或者二进制可执行文件不存在), 那么 systemctl start 将会执行失败。

  • forking

表示 ExecStart= 的命令将会在启动过程中将fork()一个新的shell执行。可以理解为在后台运行。如果命令有 --daemon 参数一定不要加。 

如果使用了此种类型,那么建议同时设置 PIDFile= 选项,以帮助 systemd 准确可靠的定位该服务的主进程。 systemd 将会在父进程退出之后 立即开始启动后继单元。

  • oneshot

oneshot 与 simple 类似,不同之处在于, 如果 "ExecStart=" 后面的程序或命令是在 当前shell 运行一下就退出的

此种类型的服务通常需要设置 RemainAfterExit= 选项。 当 Type= 与 ExecStart= 都没有设置时, Type=oneshot 就是默认值。

  • notify

notify 与 exec 类似,不同之处在于, 该服务将会在启动完成之后通过 sd_notify(3) 之类的接口发送一个通知消息。成功的发送了这个消息,systemd 才会在启动后继单元

如果设为此类型,那么下文的 NotifyAccess= 将只能设为非 none 值。如果未设置 NotifyAccess= 选项、或者已经被明确设为 none ,那么将会被自动强制修改为 main 。注意,目前 Type=notify 尚不能与 PrivateNetwork=yes 一起使用。

该守护进程必须支持 systemd 通知协议, 否则 systemd 将会认为该服务一直处于"启动中"(activating)状态,并在超时后将其杀死。


其中 [Service] 部分 Restart 里面对应命令对应的情况如下图

image.png

5、Target & Runlevel(很少用)

5.1 基本概念

Systemd 中的 target 可以理解为系统的“状态点”。一个 target 里面一般包含多个 unit(服务) ,简单点说就是包含需要启动的服务组。启动了某个 target 就意味将系统置于某个“状态点”。

Target 可以与传统的 Runlevel 相对应,它们的映射关系如下表:

image.png

需要注意的是,与 Runlevel 相对应的 Target 一定不能够同时启动。

当设置了某个服务自启动的时候,其实就是在往某个 target .wants 目录中添加服务项的符号链接而已(默认添加到 /etc/systemd/system/multi-user.target.wants )。

5.2 查看系统默认的启动级别

systemctl get-default

5.3 切换到某个启动级别

systemctl isolate <启动级别对应的 target 名>

# 如: 切换到图形界面
[root: ~]# systemctl isolate graphical.target

5.4 设置系统默认的启动级别

systemctl set-default <启动级别对应的 target 名>

6.日志管理

6.1 开启日志持久化存储

Systemd 默认只会把日志存储在内存中,一旦重启系统日志将全部丢失。所以强烈建议打开该功能。

去掉 /etc/systemd/journald.conf 这个文件内 Storage= 这一行前面的 # 号,然后将等号后面的内容改为 persistent

保存配置文件之后重启一下日志记录服务即可。

systemctl restart systemd-journald.service

6.2 查看自从 本次开机后 所有的日志 信息

journalctl [-e] [-f]
  • -e 表示输出之后跳转到末行,下同。

  • -f 表示实时滚动显示,下同。

当没有使用 -f 时,使用 PageUp 或 PageDown 翻页,查看完毕后按 q 退出。

6.3 查看特定 Unit (服务)所有的日志信息

journalctl [-e] [-f] -u <Unit 名>

6.4 查看特定时间点内所有的日志信息

journalctl --since="yyyy-MM-dd hh:mm:ss" --until="yyyy-MM-dd hh:mm:ss"


例如: 查看 2017 年 9 月 6 日 08:00:00 至 2017 年 9 月 6 日 08:20:00 之间的所有日志

[root: ~]# journalctl --since="2017-09-06 08:00:00" --until="2017-09-06 08:20:00"

6.5 查看日志当前占用的磁盘空间

journalctl --disk-usage

6.6 修改日志最大占用的磁盘空间

去掉 /etc/systemd/journald.conf 这个文件内 SystemMaxUse= 这一行前面的 # 号,然后在等号后面填上数值即可。

例如:  修改日志最大占用的磁盘空间为 50M

SystemMaxUse=50M

保存配置文件之后重启一下日志记录服务即可。

systemctl restart systemd-journald.service


参考:

systemd.service 中文手册


0
0
下一篇:了解 四种前后端接口 REST、gRPC、GraphQL、Webhooks

0 条评论

老佳啊

85后,大专学历,中原人士,家里没矿。

由于年轻时长的比较帅气,导致在别人眼里,我一直不谈恋爱的原因是清高,实则是自己的小自卑。最大的人生目标就是找一个相知相爱相容的人,共度余生。

和人相处时如果能感受到真诚,会非常注重彼此的关系,对别人没有什么心机,即使有利益冲突,一般也会以和为贵,因为在这个世界上,物质的东西,从来不会吸引到我。

特别迷恋那些大山大水,如果现在还能隐居,可能早就去了。对那些宏伟的有底蕴的人文景观比较不感冒。

从事于IT行业,却一直对厨房念念不忘,由于身材魁梧,总觉得自己上辈子是个将军,可惜这辈子没当兵,也不会打架。