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

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

复制
sudo apt install redis-server sudo systemctl start redis-server1.2.

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

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

复制
kill -9 $(pidof redis-server)1.

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

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

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

复制
sudo systemctl stop redis-server1.

果然,你又重新“夺回”了 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/systemd1.2.3.4.5.6.

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

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

但是人们厌倦了 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-server1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.

服务如何被 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 ...1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.

/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.service1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.36.37.38.39.40.41.42.43.44.45.46.

/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 systemd1.2.3.4.5.6.7.8.9.

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

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

THE END
本站服务器由亿华云赞助提供-企业级高防云服务器