服务管理

服务是在后台运行的程序,提供系统功能或网络服务。Linux使用systemd作为系统和服务管理器,通过systemctl命令管理服务。本章将深入讲解Linux服务管理的概念和实践。


一、systemd基础

1.1 systemd简介

1.1.1 什么是systemd

systemd:Linux系统的初始化系统和服务管理器。

systemd特点

  • 并行启动服务,提高启动速度
  • 按需启动守护进程
  • 自动服务依赖关系管理
  • 统一的日志系统(journald)
  • 支持快照和恢复

东巴文观点:systemd是现代Linux系统的核心,管理着系统启动和服务运行。

1.1.2 systemd组成

systemd主要组件

组件 说明
systemd 系统和服务管理器
systemctl 服务管理命令
journalctl 日志管理命令
systemd-analyze 启动分析工具
hostnamectl 主机名管理
localectl 区域设置管理
timedatectl 时间日期管理
loginctl 登录会话管理

1.1.3 systemd单元

systemd单元类型

单元类型 扩展名 说明
Service .service 服务单元
Socket .socket 套接字单元
Device .device 设备单元
Mount .mount 挂载点单元
Automount .automount 自动挂载单元
Swap .swap 交换分区单元
Path .path 路径单元
Timer .timer 定时器单元
Target .target 目标单元
Snapshot .snapshot 快照单元
Slice .slice 资源控制单元

东巴文理解:systemd通过不同类型的单元管理系统资源,service是最常用的单元类型。

1.2 查看systemd信息

1.2.1 systemd版本

# 查看systemd版本
systemctl --version

# 输出示例:
# systemd 245 (245.4-4ubuntu3)
# +PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP

1.2.2 systemd启动时间

# 查看启动时间
systemd-analyze

# 输出示例:
# Startup finished in 5.123s (kernel) + 10.456s (userspace) = 15.579s

# 查看各服务启动时间
systemd-analyze blame

# 输出示例:
#  5.123s NetworkManager-wait-online.service
#  2.456s apt-daily.service
#  1.789s snapd.service

# 查看启动关键链
systemd-analyze critical-chain

# 输出示例:
# graphical.target @10.456s
# └─multi-user.target @10.456s
#   └─NetworkManager.service @8.123s +2.333s
#     └─network-pre.target @8.123s

东巴文技巧:使用systemd-analyze blame可以找出启动慢的服务。

1.2.3 查看默认目标

# 查看默认目标
systemctl get-default

# 输出示例:
# graphical.target

# 查看所有目标
systemctl list-units --type=target

# 输出示例:
# UNIT                LOAD   ACTIVE SUB    DESCRIPTION
# basic.target        loaded active active Basic System
# graphical.target    loaded active active Graphical Interface
# multi-user.target   loaded active active Multi-User System

常用目标

目标 说明
poweroff.target 关机
rescue.target 救援模式
multi-user.target 多用户模式(无图形界面)
graphical.target 图形界面模式
reboot.target 重启

二、systemctl命令详解

2.1 服务管理

2.1.1 查看服务状态

# 查看服务状态
systemctl status nginx

# 输出示例:
# ● nginx.service - A high performance web server and a reverse proxy server
#    Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
#    Active: active (running) since Mon 2024-01-01 10:00:00 CST; 1h 30min ago
#      Docs: man:nginx(8)
#   Main PID: 1234 (nginx)
#     Tasks: 3 (limit: 4915)
#    Memory: 5.2M
#    CGroup: /system.slice/nginx.service
#            ├─1234 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
#            ├─1235 nginx: worker process
#            └─1236 nginx: worker process
#
# Jan 01 10:00:00 server systemd[1]: Starting A high performance web server...
# Jan 01 10:00:00 server systemd[1]: Started A high performance web server...

# 查看服务是否运行
systemctl is-active nginx

# 输出示例:
# active

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

# 输出示例:
# enabled

# 查看服务是否失败
systemctl is-failed nginx

# 输出示例:
# inactive

服务状态说明

状态 说明
active (running) 正在运行
active (exited) 已成功执行完成
active (waiting) 等待中
inactive 未运行
activating 正在启动
deactivating 正在停止
failed 启动失败

2.1.2 启动服务

# 启动服务
sudo systemctl start nginx

# 启动多个服务
sudo systemctl start nginx mysql

# 启动服务并显示详细输出
sudo systemctl start nginx --verbose

东巴文提示:启动服务需要root权限。

2.1.3 停止服务

# 停止服务
sudo systemctl stop nginx

# 停止多个服务
sudo systemctl stop nginx mysql

# 强制停止服务
sudo systemctl kill nginx

2.1.4 重启服务

# 重启服务
sudo systemctl restart nginx

# 重载服务配置(不中断服务)
sudo systemctl reload nginx

# 重载或重启(如果服务不支持reload,则restart)
sudo systemctl reload-or-restart nginx

东巴文理解

  • restart:完全停止再启动,服务会短暂中断
  • reload:重新加载配置,服务不中断
  • reload-or-restart:智能选择,优先reload

2.1.5 开机启动

# 设置开机启动
sudo systemctl enable nginx

# 输出示例:
# Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /lib/systemd/system/nginx.service.

# 取消开机启动
sudo systemctl disable nginx

# 输出示例:
# Removed /etc/systemd/system/multi-user.target.wants/nginx.service.

# 启用并立即启动
sudo systemctl enable --now nginx

# 禁用并立即停止
sudo systemctl disable --now nginx

# 查看是否开机启动
systemctl is-enabled nginx

东巴文最佳实践:使用enable --now可以一步完成启用和启动。

2.1.6 掩码服务

# 掩码服务(禁止启动)
sudo systemctl mask nginx

# 输出示例:
# Created symlink /etc/systemd/system/nginx.service → /dev/null.

# 取消掩码
sudo systemctl unmask nginx

# 输出示例:
# Removed /etc/systemd/system/nginx.service.

东巴文理解:掩码服务比disable更彻底,服务完全无法启动。

2.2 服务列表

2.2.1 列出所有服务

# 列出所有已加载的服务
systemctl list-units --type=service

# 输出示例:
# UNIT                LOAD   ACTIVE SUB     DESCRIPTION
# accounts-daemon.service loaded active running Accounts Service
# cron.service        loaded active running Regular background program processing daemon
# nginx.service       loaded active running A high performance web server

# 列出所有服务(包括未加载的)
systemctl list-unit-files --type=service

# 输出示例:
# UNIT FILE              STATE
# accounts-daemon.service enabled
# cron.service           enabled
# nginx.service          enabled

# 列出运行中的服务
systemctl list-units --type=service --state=running

# 列出失败的服务
systemctl list-units --type=service --state=failed

# 列出已启用的服务
systemctl list-unit-files --type=service --state=enabled

# 列出已禁用的服务
systemctl list-unit-files --type=service --state=disabled

2.2.2 服务状态过滤

# 列出所有状态的服务
systemctl list-units --all --type=service

# 列出指定状态的服务
systemctl list-units --type=service --state=active
systemctl list-units --type=service --state=running
systemctl list-units --type=service --state=exited
systemctl list-units --type=service --state=failed

# 列出最近失败的服务
systemctl --failed

2.3 服务依赖

2.3.1 查看服务依赖

# 查看服务依赖
systemctl list-dependencies nginx

# 输出示例:
# nginx.service
# ● ├─system.slice
# ● └─basic.target
#   ├─paths.target
#   ├─slices.target
#   └─sockets.target

# 查看反向依赖(哪些服务依赖此服务)
systemctl list-dependencies nginx --reverse

# 查看服务依赖树
systemctl list-dependencies nginx --plain

2.3.2 查看服务配置

# 查看服务配置文件内容
systemctl cat nginx

# 输出示例:
# /lib/systemd/system/nginx.service
# [Unit]
# Description=A high performance web server and a reverse proxy server
# After=network.target
#
# [Service]
# Type=forking
# PIDFile=/run/nginx.pid
# ExecStartPre=/usr/sbin/nginx -t
# ExecStart=/usr/sbin/nginx
# ExecReload=/bin/kill -s HUP $MAINPID
# ExecStop=/bin/kill -s QUIT $MAINPID
# PrivateTmp=true
#
# [Install]
# WantedBy=multi-user.target

# 查看服务配置文件路径
systemctl show nginx -p FragmentPath

# 输出示例:
# FragmentPath=/lib/systemd/system/nginx.service

2.4 服务属性

2.4.1 查看服务属性

# 查看所有属性
systemctl show nginx

# 查看指定属性
systemctl show nginx -p MainPID

# 输出示例:
# MainPID=1234

# 查看多个属性
systemctl show nginx -p MainPID,ExecStart

# 输出示例:
# MainPID=1234
# ExecStart={ path=/usr/sbin/nginx ; argv[]=/usr/sbin/nginx ; ignore_errors=no ; start_time=[Mon 2024-01-01 10:00:00 CST] ; stop_time=[n/a] ; pid=1234 ; code=(null) ; status=0/0 }

常用属性

属性 说明
MainPID 主进程PID
ExecStart 启动命令
ExecStop 停止命令
ExecReload 重载命令
ActiveState 活动状态
SubState 子状态
LoadState 加载状态
UnitFileState 单元文件状态

2.4.2 设置服务属性

# 设置服务属性(临时)
sudo systemctl set-property nginx MemoryLimit=512M

# 设置服务属性(永久)
sudo systemctl set-property nginx MemoryLimit=512M --runtime=no

# 查看设置
systemctl show nginx -p MemoryLimit

2.5 服务重载

# 重载systemd配置
sudo systemctl daemon-reload

# 重载所有服务
sudo systemctl daemon-reload --no-reload

# 重置失败状态
sudo systemctl reset-failed

# 重置指定服务的失败状态
sudo systemctl reset-failed nginx

东巴文提示:修改服务配置文件后,需要执行systemctl daemon-reload


三、服务配置文件

3.1 服务文件位置

服务文件存放位置

位置 优先级 说明
/etc/systemd/system/ 最高 管理员自定义
/run/systemd/system/ 运行时创建
/lib/systemd/system/ 软件包安装
/usr/lib/systemd/system/ 软件包安装

东巴文理解:优先级高的会覆盖优先级低的同名服务文件。

3.2 服务文件结构

3.2.1 基本结构

服务文件示例

[Unit]
Description=Nginx HTTP Server
Documentation=man:nginx(8)
After=network.target remote-fs.target nss-lookup.target
Wants=network-online.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target

3.2.2 [Unit]部分

[Unit]部分配置

配置项 说明
Description 服务描述
Documentation 文档地址
After 在哪些服务之后启动
Before 在哪些服务之前启动
Wants 依赖的服务
Requires 强依赖的服务
Conflicts 冲突的服务
ConditionPathExists 文件存在时才启动
ConditionPathIsDirectory 目录存在时才启动

示例

[Unit]
Description=MySQL Database Server
Documentation=man:mysqld(8)
Documentation=https://dev.mysql.com/doc/refman/en/
After=network.target
After=syslog.target
Wants=network-online.target
Requires=network.target

3.2.3 [Service]部分

[Service]部分配置

服务类型

Type 说明
simple 默认类型,ExecStart启动的进程是主进程
forking ExecStart启动的进程会fork子进程,父进程退出
oneshot 执行一次就退出
notify 服务启动完成后发送通知
dbus 服务启动后获取D-Bus名称

执行命令

配置项 说明
ExecStart 启动命令
ExecStartPre 启动前执行的命令
ExecStartPost 启动后执行的命令
ExecStop 停止命令
ExecStopPost 停止后执行的命令
ExecReload 重载命令

重启策略

Restart 说明
no 不重启(默认)
on-success 成功退出时重启
on-failure 失败退出时重启
on-abnormal 异常退出时重启
on-watchdog 看门狗超时时重启
on-abort 未捕获信号退出时重启
always 总是重启

资源限制

配置项 说明
LimitNOFILE 最大文件描述符数
LimitNPROC 最大进程数
LimitCORE 核心转储大小
MemoryLimit 内存限制
CPUShares CPU权重
BlockIOWeight IO权重

安全设置

配置项 说明
PrivateTmp 使用私有/tmp目录
NoNewPrivileges 禁止提升权限
ProtectSystem 保护系统目录
ProtectHome 保护用户主目录
ReadOnlyPaths 只读路径
ReadWritePaths 读写路径

示例

[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
Restart=on-failure
RestartSec=5s
LimitNOFILE=65535

3.2.4 [Install]部分

[Install]部分配置

配置项 说明
WantedBy 服务被哪个target依赖
RequiredBy 服务被哪个target强依赖
Also 同时安装的服务
Alias 服务别名

示例

[Install]
WantedBy=multi-user.target

3.3 创建自定义服务

3.3.1 创建简单服务

创建服务文件

sudo vim /etc/systemd/system/myapp.service

服务文件内容

[Unit]
Description=My Application
After=network.target

[Service]
Type=simple
User=dbw
Group=dbw
WorkingDirectory=/home/dbw/myapp
ExecStart=/home/dbw/myapp/myapp
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target

启用服务

# 重载systemd配置
sudo systemctl daemon-reload

# 启用并启动服务
sudo systemctl enable --now myapp

# 查看服务状态
systemctl status myapp

3.3.2 创建Python应用服务

服务文件

[Unit]
Description=Python Flask Application
After=network.target

[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory=/var/www/myapp
Environment="PATH=/var/www/myapp/venv/bin"
ExecStart=/var/www/myapp/venv/bin/python app.py
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

3.3.3 创建Node.js应用服务

服务文件

[Unit]
Description=Node.js Application
After=network.target

[Service]
Type=simple
User=node
Group=node
WorkingDirectory=/home/node/myapp
ExecStart=/usr/bin/node /home/node/myapp/app.js
Restart=on-failure
RestartSec=10
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=nodejs-app

[Install]
WantedBy=multi-user.target

3.4 修改服务配置

3.4.1 使用override.conf

创建覆盖配置

# 创建服务配置目录
sudo mkdir -p /etc/systemd/system/nginx.service.d/

# 创建覆盖配置文件
sudo vim /etc/systemd/system/nginx.service.d/override.conf

覆盖配置内容

[Service]
LimitNOFILE=65535
Restart=always
RestartSec=10s

应用配置

# 重载systemd配置
sudo systemctl daemon-reload

# 重启服务
sudo systemctl restart nginx

# 查看合并后的配置
systemctl cat nginx

东巴文最佳实践:使用override.conf修改服务配置,不直接修改原始服务文件。

3.4.2 使用systemctl edit

# 编辑服务配置(自动创建override.conf)
sudo systemctl edit nginx

# 编辑完整服务文件
sudo systemctl edit --full nginx

# 输出示例:
# [Service]
# LimitNOFILE=65535
# Restart=always

四、服务日志管理

4.1 journalctl基础

4.1.1 查看日志

# 查看所有日志
journalctl

# 查看最近的日志
journalctl -n 100

# 实时查看日志
journalctl -f

# 查看今天的日志
journalctl --since today

# 查看指定时间范围的日志
journalctl --since "2024-01-01 10:00:00" --until "2024-01-01 11:00:00"

# 查看最近一小时的日志
journalctl --since "1 hour ago"

# 查看昨天的日志
journalctl --since yesterday

4.1.2 查看服务日志

# 查看指定服务的日志
journalctl -u nginx

# 查看多个服务的日志
journalctl -u nginx -u mysql

# 实时查看服务日志
journalctl -u nginx -f

# 查看服务最近的日志
journalctl -u nginx -n 100

# 查看服务今天的日志
journalctl -u nginx --since today

# 查看服务启动失败的日志
journalctl -u nginx -p err

4.1.3 查看内核日志

# 查看内核日志
journalctl -k

# 查看内核日志(实时)
journalctl -k -f

4.1.4 按优先级查看

日志优先级

优先级 说明
0 emerg - 紧急
1 alert - 警报
2 crit - 严重
3 err - 错误
4 warning - 警告
5 notice - 通知
6 info - 信息
7 debug - 调试

查看指定优先级的日志

# 查看错误日志
journalctl -p err

# 查看警告及以上级别的日志
journalctl -p warning

# 查看指定优先级范围的日志
journalctl -p warning..err

4.2 日志过滤

4.2.1 按进程过滤

# 按PID过滤
journalctl _PID=1234

# 按UID过滤
journalctl _UID=1000

# 按GID过滤
journalctl _GID=1000

4.2.2 按用户过滤

# 查看指定用户的日志
journalctl _UID=1000

# 查看当前用户的日志
journalctl --user

4.2.3 按设备过滤

# 查看指定设备的日志
journalctl /dev/sda1

4.2.4 按可执行文件过滤

# 查看指定可执行文件的日志
journalctl /usr/sbin/nginx

4.3 日志输出格式

4.3.1 输出格式选项

# 默认格式
journalctl -u nginx -n 10

# JSON格式
journalctl -u nginx -n 10 -o json

# JSON-pretty格式
journalctl -u nginx -n 10 -o json-pretty

# 简洁格式
journalctl -u nginx -n 10 -o verbose

# 猫格式(只显示消息)
journalctl -u nginx -n 10 -o cat

# 导出格式
journalctl -u nginx -n 10 -o export

4.3.2 日志大小

# 查看日志大小
journalctl --disk-usage

# 输出示例:
# Archived and active journals take up 128.0M on disk.

# 清理日志(保留最近100MB)
sudo journalctl --vacuum-size=100M

# 清理日志(保留最近7天)
sudo journalctl --vacuum-time=7d

# 清理日志(保留最近10个日志文件)
sudo journalctl --vacuum-files=10

4.4 日志持久化

4.4.1 配置日志持久化

编辑journald配置

sudo vim /etc/systemd/journald.conf

配置内容

[Journal]
# 存储模式:auto、volatile、persistent
Storage=persistent

# 日志最大大小
SystemMaxUse=500M

# 日志最大文件数
SystemMaxFileSize=100M

# 日志保留时间
MaxRetentionSec=1month

# 是否转发到syslog
ForwardToSyslog=yes

# 是否转发到控制台
ForwardToConsole=no

重启journald服务

sudo systemctl restart systemd-journald

东巴文提示:设置Storage=persistent后,日志会保存到/var/log/journal/目录。


五、传统服务管理

5.1 service命令

service命令:传统的SysVinit服务管理命令。

# 启动服务
sudo service nginx start

# 停止服务
sudo service nginx stop

# 重启服务
sudo service nginx restart

# 重载服务
sudo service nginx reload

# 查看服务状态
sudo service nginx status

# 查看所有服务状态
sudo service --status-all

东巴文提示:service命令实际上是调用systemctl,建议直接使用systemctl。

5.2 chkconfig命令

chkconfig命令:传统的SysVinit服务开机启动管理命令。

# 查看服务开机启动状态
chkconfig --list

# 设置服务开机启动
sudo chkconfig nginx on

# 取消服务开机启动
sudo chkconfig nginx off

# 添加服务
sudo chkconfig --add nginx

# 删除服务
sudo chkconfig --del nginx

东巴文提示:chkconfig命令在新系统中已不推荐使用,建议使用systemctl。


六、本章小结

6.1 核心要点

✅ 理解systemd的概念和组成 ✅ 掌握systemctl命令的使用 ✅ 学会创建和管理服务 ✅ 熟练使用journalctl查看日志

6.2 验证清单

完成本章学习后,请确认您能够:

  • 使用systemctl管理服务
  • 查看服务状态和日志
  • 创建自定义服务
  • 配置服务开机启动
  • 使用journalctl查看和分析日志

东巴文(db-w.cn) - 让Linux学习更简单