linux-定义和管理系统服务service

linux-定义和管理系统服务service


前篇

在Linux系统中,service 文件(也称为 systemd 单元文件)用于定义和管理系统服务。systemd 是现代Linux发行版中用于启动、停止、启用和管理服务的初始化系统。service 文件通常存放在 /etc/systemd/system//lib/systemd/system/ 目录中,文件名以 .service 结尾。


service 文件的基本结构

一个典型的 service 文件包含以下几个部分:

  1. [Unit] 部分:描述服务的元数据,如服务的描述、依赖关系等。
  2. [Service] 部分:定义服务的行为和启动方式。
  3. [Install] 部分:定义服务的安装信息,指定服务在系统启动时的行为。

示例 service 文件

以下是一个 service 文件的示例,假设你要创建一个服务来运行一个简单的Python脚本。

1. 创建一个简单的Python脚本

首先,假设你有一个名为 my_script.py 的Python脚本,存放在 /usr/local/bin/ 目录下。

1
2
3
4
5
6
#!/usr/bin/env python3
import time

while True:
print("Service is running...")
time.sleep(60)

确保脚本是可执行的:

1
$ chmod +x /usr/local/bin/my_script.py

2. 创建 service 文件

现在,你可以为这个脚本创建一个 service 文件。假设服务名为 my_service,你可以在 /etc/systemd/system/ 目录下创建 my_service.service 文件。

1
$ vim /etc/systemd/system/my_service.service

在文件中写入以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
[Unit]
Description=My Custom Python Script Service
After=network.target

[Service]
ExecStart=/usr/local/bin/my_script.py
Restart=always
User=nobody
Group=nogroup
Environment=PYTHONUNBUFFERED=1

[Install]
WantedBy=multi-user.target

3. 说明

  • [Unit] 部分:
    • Description: 服务的简短描述。
    • After: 定义服务启动的顺序,这里表示在 network.target 之后启动。
  • [Service] 部分:
    • ExecStart: 定义服务启动时执行的命令,这里是运行Python脚本。
    • Restart: 定义服务在失败时是否重启,always 表示无论何种原因服务停止都将重启。
    • UserGroup: 定义服务以哪个用户和组的身份运行。
    • Environment: 设置环境变量,这里设置了 PYTHONUNBUFFERED=1 以确保Python输出不被缓冲。
  • [Install] 部分:
    • WantedBy: 定义服务的目标环境。multi-user.target 是一个常见的运行级别,相当于传统的运行级别3(没有图形界面的多用户模式)。

4. 使服务生效并启动服务

  • 重新加载 systemd 配置: 在创建或修改 service 文件后,需要让 systemd 重新加载配置:

    1
    $ systemctl daemon-reload
  • 启动服务: 使用以下命令启动服务:

    1
    $ systemctl start my_service
  • 启用服务开机自启动: 如果你希望服务在系统启动时自动启动,可以使用以下命令:

    1
    $ systemctl enable my_service
  • 检查服务状态: 你可以使用以下命令检查服务的状态:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    $ sudo systemctl status my_service

    root@itssg:~# systemctl status my_service.service
    ● my_service.service - its nas service
    Loaded: loaded (/etc/systemd/system/test_v2ray.service; enabled; vendor preset: enabled)
    Active: active (running) since Tue 2024-08-13 00:42:23 CST; 6s ago
    Main PID: 73425 (v2ray)
    Tasks: 8 (limit: 4459)
    Memory: 121.6M
    CGroup: /system.slice/my_service.service
    └─73425 /root/v2ray/v2ray run -config /root/v2ray/myconfig.json // 73425 就是进程号

    Aug 13 00:42:23 yangxuan-tg-bot-01 systemd[1]: Started its nas service.
  • 停止服务: 如果需要停止服务,可以使用以下命令:

    1
    $ systemctl stop my_service
  • 禁用服务开机自启动: 如果你不再需要服务在开机时自动启动,可以使用以下命令禁用它:

    1
    $ systemctl disable my_service

总结

service 文件是 systemd 中定义和管理服务的重要配置文件,通过它可以详细控制服务的启动、停止、重启以及开机自启动行为。使用 systemdservice 文件可以有效地管理和自动化系统服务。


Environment 设置环境变量

systemdservice 文件中,Environment 选项用于设置环境变量。你可以使用它来定义服务运行时所需的环境变量。这些变量可以被服务的启动命令(ExecStart)和其他命令使用。

1. 单个环境变量

你可以在 [Service] 部分使用 Environment 选项来设置单个环境变量。格式如下:

1
2
[Service]
Environment="VAR_NAME=value"

示例

1
2
3
4
5
6
7
8
9
[Unit]
Description=Example Service

[Service]
ExecStart=/usr/local/bin/my_script.sh
Environment="MY_VAR=my_value"

[Install]
WantedBy=multi-user.target

在这个例子中,MY_VAR 环境变量被设置为 my_value,并且可以在 my_script.sh 脚本中访问。

2. 多个环境变量

如果你需要设置多个环境变量,可以在多个 Environment 行中定义它们:

1
2
3
[Service]
Environment="VAR1=value1"
Environment="VAR2=value2"

示例

1
2
3
4
5
6
7
8
9
10
11
[Unit]
Description=Example Service with Multiple Environment Variables

[Service]
ExecStart=/usr/local/bin/my_script.sh
Environment="VAR1=value1"
Environment="VAR2=value2"
Environment="VAR3=value3"

[Install]
WantedBy=multi-user.target

在这个例子中,VAR1VAR2VAR3 都被定义为环境变量,并且它们的值可以在脚本中使用。

3. 从文件加载环境变量

如果你有一个文件中包含多个环境变量,可以使用 EnvironmentFile 选项从文件中加载这些变量。

文件格式

环境变量文件的格式是简单的 KEY=VALUE 形式,每行一个变量。例如,创建一个文件 /etc/my_service.env

1
2
VAR1=value1
VAR2=value2
使用 EnvironmentFile

service 文件中,可以像这样引用该文件:

1
2
3
[Service]
ExecStart=/usr/local/bin/my_script.sh
EnvironmentFile=/etc/my_service.env

这样,/etc/my_service.env 文件中的所有环境变量都会被加载,并且可以在 ExecStart 命令中使用。

示例:结合 EnvironmentEnvironmentFile

1
2
3
4
5
6
7
8
9
10
[Unit]
Description=Example Service with Environment Variables from File

[Service]
ExecStart=/usr/local/bin/my_script.sh
Environment="VAR3=value3"
EnvironmentFile=/etc/my_service.env

[Install]
WantedBy=multi-user.target

在这个示例中,/etc/my_service.env 文件中的变量和 VAR3=value3 都将被加载。

总结

  • Environment: 直接在 service 文件中定义单个或多个环境变量。
  • EnvironmentFile: 从文件中加载环境变量,适用于需要管理多个变量或敏感信息(如密码)。

EnvironmentEnvironmentFile 选项可以灵活地帮助你管理服务所需的环境变量。


命令

  • 重载系统服务

    修改 .service 后都要执行这个命令

    1
    $ systemctl daemon-reloads
  • 启动服务

    1
    $ systemctl start test_v2ray.service
  • 停止服务

    1
    $ systemctl stop test_v2ray.service
  • 查看服务状态

    1
    2
    3
    4
    5
    6
    $ systemctl status test_v2ray.service 

    ● test_v2ray.service - its v2ray service
    Loaded: loaded (/etc/systemd/system/test_v2ray.service; enabled; vendor preset: enabled)
    Active: active (running) since Tue 2024-08-13 00:50:49 CST; 23min ago
    Main PID: 914888 (v2ray) // 914888 就是进程号
  • 开机自启动

    • 注册 开机自启动服务

      1
      2
      3
      $ systemctl enable test_v2ray.service 

      Created symlink /etc/systemd/system/multi-user.target.wants/test_v2ray.service → /etc/systemd/system/test_v2ray.service.
    • 取消 开机自启动

      1
      2
      3
      $ systemctl disable test_v2ray.service

      Removed /etc/systemd/system/multi-user.target.wants/test_v2ray.service
    • 查看 所有 开机自启动的服务

      1
      2
      3
      4
      5
      6
      7
      8
      $ systemctl list-unit-files --type=service | grep enabled

      UNIT FILE STATE VENDOR PRESET
      test_feishubot.service enabled enabled
      test_flag.service disabled enabled
      test_nas.service enabled enabled
      test_v2ray.service enabled enabled
      udev.service static enabled
      • 第一个状态
        • **enabled**:服务配置为开机自启动。
        • **disabled**:服务未配置为开机自启动,但可以手动启动。
        • **static**:服务不能直接启用或禁用,通常是作为依赖被其他服务调用。
      • 第二个状态表示是否可用
    • 查看 某个服务 是否开机自启动

      1
      2
      3
      $ systemctl is-enabled test_flag.service 

      disabled

      也可以通过 status 命令查看

      1
      2
      3
      4
      # systemctl status test_flag.service 

      ● test_flag.service - Hi, body. Test Service
      Loaded: loaded (/etc/systemd/system/test_flag.service; disabled; vendor preset: enabled) // disabled 就是是否开机启动的标记
  • 查看当前 正在运行 的服务

    1
    2
    3
    4
    5
    6
    $ systemctl list-units --type=service --state=running

    UNIT LOAD ACTIVE SUB DESCRIPTION
    test_feishubot.service loaded active running its feishu bot service
    test_flag.service loaded active running Hi, body. Test Service
    test_nas.service loaded active running its nas service
  • 查看哪些服务是通过目标(target)启用的

    systemd 中,服务通常被配置为在某个特定的目标(如 multi-user.target)下启动。你可以查看某个目标下的所有服务:

    1
    2
    3
    4
    5
    6
    7
    8
    # systemctl list-dependencies multi-user.target

    multi-user.target
    ● ├─aegis.service
    ● ├─aliyun.service
    ● ├─test_feishubot.service
    ● ├─test_nas.service
    ● ├─test_v2ray.service