「我的 Redis Server 关不掉了!」认识 systemd / systemctl Linux 服务管理工具

系统 Linux
systemd 是一个 Linux 系统基础组件的集合,它提供了一系列强大的功能来管理系统的启动、服务、进程以及资源等。通过 systemd 这些单元的配置和组合,可以灵活地控制系统的各种行为。

你需要一个 Redis 服务做开发调试,于是你照着教程在一台平平无奇的 Ubunut 安装 Redis 服务并且启动:

sudo apt install redis-server
sudo systemctl start redis-server

接着,你的另一个服务需要用到 6379 端口,但是此时因为 6379 端口被 Redis 服务占用,所以你无法启动另一个服务。

因此你决定要 kill 掉 Redis 服务:

kill -9 $(pidof redis-server)

结果,却怎么也无法 kill 掉 Redis 服务。

一时间,你陷入了一个尴尬的境地,去搜索“我的 Redis 怎么也关不掉”,却发现别人面临的场景总是奇奇怪怪,而你,刚刚只是简单地在本地安装了一个 Redis 服务。

终于,你想到,你是用 systemctl 来 start 你的 Redis 服务的,那么,你可以试试用 systemctl 来 stop 你的 Redis 服务?

sudo systemctl stop redis-server

果然,你又重新“夺回”了 6379 的控制权,你终于可以愉快地启动你的另一个服务了。

于是你下定决心,了解下 systemctl 到底是个什么东西。

首先介绍 systemd

systemd 是一个 Linux 系统基础组件的集合,它提供了一系列强大的功能来管理系统的启动、服务、进程以及资源等。通过 systemd 这些单元的配置和组合,可以灵活地控制系统的各种行为。

人话:systemd 可以理解为大多数 Linux 发行版中用于取代 SysVinit 的初始化系统。如果你去看你 Linux 的第一个进程,你会发现它是 systemd ( sbin/init 是 systemd 的软链接)。

$ ps aux|head -2
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.0  0.6 168980 12544 ?        Ss    2023   7:02 /sbin/init noibrs

$ ls -lha /sbin/init
lrwxrwxrwx 1 root root 20 Jan 10  2022 /sbin/init -> /lib/systemd/systemd

操作系统中的第一个进程,其作用可以理解为:

  • 初始化内存管理系统,确定系统内存的布局与可分配资源
  • 启动文件系统的相关服务,还会创建并初始化系统的基础服务进程,像负责网络通信的守护进程等
  • 是开机后的第一个进程,负责启动其他进程,是所有进程的父进程

但是人们厌倦了 SysVinit 的复杂,于是就有了 systemd 。

systemctl 则是 systemd 的命令行工具,它提供了一组命令来管理系统服务。通过 systemctl ,你可以启动、停止、重启、查看服务的状态。

与之类似,还有 journalctl ,它是 systemd 的日志管理工具,用于查看系统服务的日志。

systemctl 常用命令

# 查看服务状态
systemctl status redis-server

# 启动服务
systemctl start redis-server

# 停止服务
systemctl stop redis-server

# 重启服务
systemctl restart redis-server

# 查看服务是否开机启动
systemctl is-enabled redis-server

# 开机启动服务
systemctl enable redis-server

# 取消开机启动服务
systemctl disable redis-server

# 查看服务日志
journalctl -u redis-server

# 查看服务依赖关系
systemctl list-dependencies redis-server

服务如何被 systemd 管理

在你 apt install 一个服务的时候,系统会自动帮你创建一个 .service 文件,这个文件就是 systemd 管理的服务的配置文件。

比如 apt install redis-server 之后,你可以看到如下文件。

$ cat /etc/init.d/redis-server
#! /bin/sh
### BEGIN INIT INFO
# Provides:             redis-server
# Required-Start:       $syslog $remote_fs
# Required-Stop:        $syslog $remote_fs
# Should-Start:         $local_fs
# Should-Stop:          $local_fs
# Default-Start:        2 3 4 5
# Default-Stop:         0 1 6
# Short-Description:    redis-server - Persistent key-value db
# Description:          redis-server - Persistent key-value db
### END INIT INFO


PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/bin/redis-server
DAEMON_ARGS=/etc/redis/redis.conf
...

/etc/init.d/redis-server 是为了兼容 SysVinit 而存在的,并不会被 systemd 所使用。你可以看到其直接书写 shell 脚本,这点为人诟病(不安全、不方便),在 systemd 中,我们可以使用配置文件来管理服务。

$ cat /etc/systemd/system/redis.service
[Unit]
Description=Advanced key-value store
After=network.target
Documentation=http://redis.io/documentation, man:redis-server(1)

[Service]
Type=forking
ExecStart=/usr/bin/redis-server /etc/redis/redis.conf
PIDFile=/run/redis/redis-server.pid
TimeoutStopSec=0
Restart=always
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=2755

UMask=007
PrivateTmp=yes
LimitNOFILE=65535
PrivateDevices=yes
ProtectHome=yes
ReadOnlyDirectories=/
ReadWritePaths=-/var/lib/redis
ReadWritePaths=-/var/log/redis
ReadWritePaths=-/var/run/redis

NoNewPrivileges=true
CapabilityBoundingSet=CAP_SETGID CAP_SETUID CAP_SYS_RESOURCE
MemoryDenyWriteExecute=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectControlGroups=true
RestrictRealtime=true
RestrictNamespaces=true
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX

# redis-server can write to its own config file when in cluster mode so we
# permit writing there by default. If you are not using this feature, it is
# recommended that you replace the following lines with "ProtectSystem=full".
ProtectSystem=true
ReadWriteDirectories=-/etc/redis

[Install]
WantedBy=multi-user.target
Alias=redis.service

/etc/systemd/system/redis.service 是 systemd 管理的服务的配置文件,你可以看到其使用了 systemd 的配置语法。

systemd 的相关守护进程们,会根据这些配置文件,达到程序预期的目的。

$ ps aux|grep systemd
root         225  0.0  7.6 211704 154572 ?       S<s   2023   4:27 /lib/systemd/systemd-journald
root         253  0.0  0.2  21664  5188 ?        Ss    2023   1:31 /lib/systemd/systemd-udevd
systemd+     406  0.0  0.3  27428  7608 ?        Ss    2023   2:42 /lib/systemd/systemd-networkd
systemd+     422  0.0  0.5  24580 12048 ?        Ss    2023   9:48 /lib/systemd/systemd-resolved
message+     446  0.0  0.2   7424  4260 ?        Ss    2023   0:08 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
root         459  0.0  0.3  17532  7868 ?        Ss    2023   0:59 /lib/systemd/systemd-logind
root     1572894  0.0  0.4  18824  9048 ?        Ss   00:20   0:00 /lib/systemd/systemd --user
root     1573931  0.0  0.0   9032   736 pts/2    S+   00:39   0:00 grep --color=auto systemd

如果我自己安装的 binary 文件,没有通过 apt install 安装,那怎么办呢?

很简单,根据需求,自己写一个 .service 文件,然后放到 /etc/systemd/system/ 目录下,然后执行 systemctl enable xxx.service 即可。

责任编辑:武晓燕 来源: Piper蛋窝
相关推荐

2021-03-04 12:55:01

systemd进程管理工具Linux

2021-03-17 10:29:35

systemdLinux管理工具

2011-04-13 16:21:22

SQL Server管理

2010-11-08 09:27:21

SQL Server管

2020-04-29 09:42:51

Linux 服务器 工具

2024-12-30 07:10:00

Linux服务器管理工具服务器

2021-01-14 15:41:22

LinuxSupervisor命令

2020-01-17 08:00:00

Linux系统管理工具系统管理员

2010-02-24 17:07:20

2010-10-20 16:30:07

Sql server管

2009-06-16 09:15:34

WebminLinux用户管理

2013-03-20 10:19:17

RedisRedis-senti监控

2011-08-12 10:38:09

MongoDB

2019-11-27 14:00:32

MySQLphpMyAdmin电脑

2015-04-17 11:29:22

Linux进程管理工具

2010-08-25 10:50:14

Linux命令

2023-03-07 14:21:57

2010-01-15 22:29:11

2010-05-25 18:36:54

MySQL管理工具

2024-09-23 17:09:28

点赞
收藏

51CTO技术栈公众号