systemd服务配置文件.service的配置项说明
.service文件的作用service 服务配置文件是 systemd 初始化系统的核心组件用于定义 Linux 服务的启动、运行和管理行为。.service文件定义单个服务的行为与管理规则配置文件包含三个主要区块以下是各配置项的详细说明一、[Unit]区块定义服务元信息和依赖关系Description服务的简短描述如DescriptionMySQL Database Server用于日志和管理命令中的标识。Documentation服务文档链接如手册页或在线文档例如Documentationman:mysqld(8)。After/BeforeAfter指定当前服务在哪些目标/服务之后启动如Afternetwork.targetBefore指定当前服务在哪些目标/服务之前启动⚠️ 仅控制启动顺序不涉及依赖关系。Requires/WantsRequires强依赖指定服务必须正常运行如Requirespostgresql.serviceWants弱依赖指定服务若失败不影响当前服务如Wantssshd.serviceConflicts定义冲突服务如Conflictsfirewalld.service冲突服务运行时当前服务无法启动。配置项说明示例Description服务的简短描述必填项用于日志标识和管理命令显示DescriptionNginx Web ServerDocumentation服务文档链接手册页或在线文档Documentationman:nginx(8)After/Before启动顺序控制-After指定当前服务在哪些目标/服务之后启动如Afternetwork.target-Before指定在哪些目标/服务之前启动⚠️ 仅控制顺序不建立强依赖。Aftersyslog.target postgresql.serviceRequires强依赖指定服务必须成功运行依赖服务失败则当前服务停止Requirespostgresql.serviceWants弱依赖指定服务若失败不影响当前服务运行Wantssshd.serviceConflicts冲突服务指定与当前服务互斥的服务冲突服务运行时当前服务无法启动Conflictsfirewalld.servicePartOf用于定义服务与其所属单元组如 target 或服务之间的关联关系。关联组。当指定的单元停止时当前服务也会自动停止但指定单元启动时不会自动触发当前服务启动。常用于会话管理服务。1. 启动行为不触发自动启动当PartOf指定的单元组如graphical-session.target启动时当前服务不会自动启动。例如用户登录图形界面后graphical-session.target激活但PartOf关联的服务需通过其他方式触发启动如依赖的WantedBy或手动启动。2. 停止行为同步停止当PartOf指定的单元组停止时当前服务会自动停止5。例如用户注销导致graphical-session.target停止时所有PartOf关联的服务将同步终止。PartOfgraphical-session.target二、[Service]区块定义服务运行行为Type进程启动类型类型说明simple默认值。ExecStart启动的进程即为主进程。适用于前台运行的程序非守护进程。systemd 认为进程创建即启动成功。forking适用于传统守护进程。主进程启动后 fork 出子进程然后主进程退出。通常需配合PIDFile使用以便 systemd 跟踪主进程。oneshot适用于一次性任务如初始化脚本。执行完命令后即退出。若希望服务状态保持“active”需配合RemainAfterExityes。notify服务启动完成后通过sd_notify()向 systemd 发送就绪信号。适用于启动较慢或需要精确知道就绪状态的服务。dbus服务在 D-Bus 总线上注册名称后才算启动成功。需配置BusName。idle类似于 simple但会延迟执行直到系统没有其他活跃任务为止。常用于避免输出干扰控制台登录过程。核心执行命令ExecStart必需项启动服务的绝对路径命令如ExecStart/usr/sbin/nginxExecStop停止服务时执行的命令ExecReload重载配置时执行的命令Restart服务失败时的重启策略no不重启默认on-failure仅在非正常退出退出码非0、被信号杀死、超时等时重启always无论何种原因退出均无条件重启on-success: 仅在正常退出退出码为0时重启on-abnormal: 仅在被信号终止或超时时重启RestartSec: 重启前的等待时间。例如RestartSec5s防止服务因快速崩溃重启导致 CPU 飙升User/Group指定运行服务的用户和组如Usernginx避免使用 root 权限。Environment/EnvironmentFileEnvironment直接设置环境变量如EnvironmentPATH/usr/binEnvironmentFile从文件加载变量如EnvironmentFile/etc/sysconfig/nginxWorkingDirectory服务的工作目录如WorkingDirectory/var/www配置项说明示例Type进程启动类型-simple主进程由ExecStart直接启动默认值-forking服务后台化需配合PIDFile-oneshot执行一次性任务-notify通过sd_notify()发送就绪信号TypeforkingExecStart启动命令必填项必须是绝对路径ExecStart/usr/sbin/nginx -c /etc/nginx/nginx.confExecStop/ExecReload自定义停止/重载命令ExecStop/usr/sbin/nginx -s quitRestart失败重启策略-no不重启默认-on-failure非正常退出时重启-always无条件重启Restarton-failureUser/Group指定运行服务的用户和组建议非 rootUsernginxEnvironment设置环境变量支持多个变量EnvironmentPATH/usr/binEnvironmentFile从文件加载环境变量EnvironmentFile/etc/sysconfig/nginxWorkingDirectory服务工作目录WorkingDirectory/var/wwwPIDFile指定 PID 文件路径Typeforking时必需PIDFile/run/nginx.pid三、[Install]区块定义服务安装目标WantedBy指定服务关联的 systemd 目标target启用服务时会创建符号链接如WantedBymulti-user.target表示关联到多用户模式RequiredBy类似WantedBy但表示强依赖关系较少使用Alias为服务启用时指定别名如Aliasweb-server.service配置项说明示例WantedBy关联启动目标指定服务启用时关联的 systemd 目标target启用服务后自动创建符号链接指定服务被哪个 Target目标所“需要”。相当于传统 SysVinit 的运行级别。multi-user.target(多用户命令行模式类似运行级别3)graphical.target(图形界面模式类似运行级别5)RequiredBy类似WantedBy但表示强依赖关系较少使用较少使用意味着如果该服务启动失败对应的 Target 也会失败。RequiredBygraphical.targetAlias为服务指定别名Aliasweb-server.service四、 配置生效与管理流程编写完.service文件后需将其放置在以下目录之一优先级从高到低/etc/systemd/system/管理员自定义配置推荐存放位置。/run/systemd/system/运行时动态生成重启后丢失。/usr/lib/systemd/system/软件包安装时的默认配置不建议直接修改。使配置生效的步骤重载配置每次新增或修改 service 文件后必须通知 systemd 重新加载配置。sudo systemctl daemon-reload启动服务sudo systemctl start myservice.service查看状态检查服务是否正常运行排查错误主要靠此命令。sudo systemctl status myservice.service设置开机自启sudo systemctl enable myservice.service查看日志如果服务启动失败查看详细日志。sudo journalctl -u myservice.service -e 配置示例Nginx 服务[Unit] DescriptionNginx Web Server Afternetwork.target Wantsnetwork-online.target [Service] Typeforking PIDFile/run/nginx.pid ExecStart/usr/sbin/nginx ExecReload/usr/sbin/nginx -s reload ExecStop/usr/sbin/nginx -s quit Usernginx Groupnginx [Install] WantedBymulti-user.target此配置确保 Nginx 在网络就绪后启动支持标准的进程管理操作。 关键注意事项配置生效修改后需执行systemctl daemon-reload权限控制避免使用root用户运行服务调试工具systemctl status 服务名和journalctl -u 服务名用于查看状态与日志通过合理配置这些选项可实现服务的精细化管理和安全运行。.target文件的作用定义系统状态或运行级别本质是单元集合抽象系统状态multi-user.target多用户命令行模式类似传统 runlevel 3graphical.target图形界面模式类似 runlevel 5rescue.target救援模式单用户维护环境管理单元依赖通过Wants、Requires等指令聚合服务如图形目标依赖多用户目标启动目标时自动触发关联的所有服务控制系统启动流程default.target指定系统默认进入的目标符号链接指向实际目标文件使用systemctl isolate graphical.target动态切换状态示例定义图形界面需启动的服务组如桌面环境、显示管理器 核心差异总结特性.service文件.target文件功能定位管理单个服务的行为定义系统状态服务集合核心配置进程启动命令、依赖、权限控制单元聚合与状态切换逻辑操作影响控制服务的启停、重启、日志等控制一组服务的协同启动或状态切换典型应用Nginx/MySQL 等后台服务多用户模式、图形界面等系统级目标通过组合使用可实现服务的精细化管理和系统状态的无缝切换。[Service] 部分配置项详解TypeType是[Service]部分最关键的配置之一它告诉 systemd如何理解和管理你的服务进程。根据服务的不同特性是前台进程、传统守护进程还是一次性任务选择正确的Type至关重要。下面是各个类型的详细解读 各类型详解simple(默认值)行为这是默认值。systemd 认为由ExecStart启动的进程就是服务的主进程。一旦该进程被创建fork()返回systemd 就认为服务已启动成功并立即开始启动后续依赖的单元。适用场景适用于绝大多数前台运行、不派生fork子进程的服务如大多数用 Python、Node.js 或 Go 编写的网络服务。示例[Service] Typesimple ExecStart/usr/bin/python3 /path/to/app.py注意由于 systemd 不等待程序初始化完成如果该服务需要向其他进程提供服务其通信渠道如端口必须在启动前就绪。exec行为与simple类似但 systemd 会一直等待直到ExecStart指定的进程真正执行完成即execve()系统调用成功后才认为服务启动完成并继续启动后续单元。适用场景当你需要确保ExecStart指定的程序本身被成功执行而不是仅仅fork成功之后再启动其他服务时使用。示例[Service] Typeexec ExecStart/usr/local/bin/my-daemonforking行为systemd 认为ExecStart启动的进程会通过fork()系统调用创建一个子进程然后父进程退出。systemd 将父进程退出视为服务启动成功的信号。适用场景这是为传统的 Unix 守护进程daemon设计的。很多用 C 或 C 编写的、会自身 daemonize 的服务都属于此类。示例[Service] Typeforking ExecStart/usr/sbin/httpd PIDFile/run/httpd/httpd.pid注意强烈建议同时使用PIDFile选项指定守护进程的 PID 文件路径以便 systemd 能准确追踪主进程。oneshot行为服务执行一个一次性任务进程启动后执行完即退出。systemd 会等待该进程退出后才认为服务启动完成并继续执行后续单元。适用场景非常适合只在启动时运行一次的脚本或命令如文件系统检查、清理临时目录、加载内核模块等。通常与RemainAfterExityes结合使用让服务在退出后仍保持在 active 状态。示例[Service] Typeoneshot ExecStart/usr/local/bin/cleanup-tmp.sh RemainAfterExityesdbus行为与simple类似但 systemd 会等待直到服务的主进程成功在 D-Bus 总线上获取到指定的名称BusName后才认为服务启动完成。适用场景适用于依赖于 D-Bus 进行通信的服务。示例[Service] Typedbus BusNameorg.example.MyService ExecStart/usr/bin/my-dbus-service注意使用此类型必须设置BusName。notify行为与simple类似但 systemd 会等待直到服务进程通过sd_notify()函数或systemd-notify命令发送一个 READY1 的通知消息后才认为服务启动完成。Typenotify是 systemd 的一种服务类型它要求主进程即ExecStart启动的进程在完成初始化后通过sd_notify()函数或systemd-notify命令向 systemd 发送READY1信号表示服务已就绪。systemd 会一直等待该信号超时时间由TimeoutStartSec控制收到后才认为服务启动成功。适用场景适用于支持 systemd 通知协议的现代服务允许服务在完成所有内部初始化如加载配置、连接数据库后再精确地通知 systemd“我准备好了”。示例[Service] Typenotify ExecStart/usr/bin/my-modern-daemon注意服务代码中需要调用sd_notify(0, READY1)。idle行为行为与simple类似但 systemd 会延迟执行该服务直到所有其他活动的任务jobs都处理完毕之后再启动它。适用场景主要用于避免服务的输出与其它服务的终端输出混杂在一起让输出更清晰。示例[Service] Typeidle ExecStart/usr/local/bin/verbose-startup-script.sh注意此类型并非通用的排序工具且有 5 秒的超时限制。⚙️ 如何选择快速决策指南我的程序是前台运行的如 Python/Node.js 脚本➡️ 使用simple默认或exec。我的程序是传统的守护进程会自己 fork 到后台➡️ 使用forking并设置PIDFile。我的程序只是一个执行完就退出的脚本或命令➡️ 使用oneshot通常配合RemainAfterExityes。我的程序需要通过 D-Bus 与其他进程通信➡️ 使用dbus并设置BusName。我的程序在启动时需要较长时间初始化完成后想主动通知 systemd➡️ 使用notify并在代码中发送READY1通知。补充说明部分 systemd 版本还支持notify-reload类型它是notify的扩展允许服务在重载时也发送通知。ExitTypeExitType是 systemd 中一个相对较新的配置项它和Type有点类似不过Type定义的是服务如何启动而ExitType定义的是 systemd 如何判断服务退出-。简单来说ExitType告诉 systemd“当发生什么情况时才算这个服务已经彻底退出了”它主要有两个可选值main(默认值)这是 systemd 一直以来的默认行为。行为systemd 会监控由Type定义的那个主进程main process。只要这个主进程还在运行服务就被视为运行中一旦主进程退出systemd 就认为整个服务已经停止。适用场景这是最常规、最推荐的设置-。如果你的服务有一个明确的、核心的主进程例如绝大多数传统的服务器守护进程就应该使用ExitTypemain。cgroup这是一个较新的选项用于处理更复杂的进程模型。行为systemd 不会只盯着一个主进程而是会监控该服务所属的整个控制组cgroup。只要该 cgroup 内还有任何一个进程在运行systemd 就认为服务仍在运行。只有当 cgroup 内的所有进程都退出后服务才会被视为停止。退出状态服务的最终退出状态将由 cgroup 中最后一个退出的进程的退出码来决定。设计目的这个选项主要是为那些进程模型不明确或没有单一主进程的应用设计的。典型场景最常见于桌面环境中的图形应用或由xdg-autostart-generator自动生成的临时服务。一个典型的例子是某个应用启动后其主进程会立即退出但会留下一个后台进程如托盘图标继续运行。如果使用ExitTypemain主进程一退出systemd 就会认为服务结束并清理掉整个 cgroup导致后台进程也被杀掉。而使用ExitTypecgroup就能避免这个问题因为 systemd 会等待 cgroup 内所有进程退出。⚙️ 如何选择快速决策指南我的服务有明确的主进程吗如 Nginx、MySQL、Python Web 应用➡️ 使用ExitTypemain默认值通常无需显式设置。这是最清晰和推荐的做法-。我的服务会派生出多个进程且“主进程”的概念很模糊吗➡️ 可以考虑使用ExitTypecgroup。我的服务是一个会“fork and exit”的图形应用吗➡️ExitTypecgroup正是为了解决这类问题而设计的。⚠️ 注意事项并非万能ExitTypecgroup主要解决的是“何时停止”的问题。如果你的服务需要精细的进程管理使用cgroup可能不如传统的main模式直观。版本要求ExitType是一个较新的特性请确保你的 systemd 版本支持它一般在 v247 之后的版本。与Type的关系ExitType需要和Type配合使用。例如Typeforking通常与ExitTypemain是经典组合。在使用ExitTypecgroup时Type通常设置为simple或exec。总的来说除非你明确遇到了“主进程退出但子进程需要继续运行”的问题否则保持默认的ExitTypemain就是最佳实践。RestartRestart配置项定义了 systemd 在服务进程退出后何时以及是否自动重启该服务。这是实现服务高可用和故障自愈的核心机制。 Restart 可取值详解Restart有以下常用取值取值行为典型场景no(默认值)服务进程退出后永不自动重启。适用于执行一次性任务的服务。always无论退出状态如何正常或异常都会无条件重启。适用于必须持续运行的核心服务如sshd。on-success仅当服务进程正常退出退出码为0时才重启。使用场景较少。on-failure仅当服务进程异常退出时才重启。长时间运行服务的最佳实践。on-abnormal仅当服务进程被信号终止、超时或看门狗超时等异常情况时才重启。适用于希望服务自主决定退出的场景。on-abort仅当服务进程因未被捕获的信号如SIGABRT而退出时才重启。较少单独使用。on-watchdog仅当服务的看门狗超时时才重启。使用了WatchdogSec的服务。 触发条件详解不同取值的触发条件有所不同on-failure触发条件退出码不为 0。被非正常信号终止如SIGSEGV段错误、SIGABRT中止等。启动或停止超时(TimeoutStartSec/TimeoutStopSec)。on-abnormal触发条件被任何信号终止除了SIGHUP、SIGINT、SIGTERM、SIGPIPE这四种。操作超时。注意通过systemctl stop手动停止服务属于管理员的有意操作不会触发任何自动重启。 推荐实践与关键配置推荐值对于需要长期运行的服务官方手册推荐的设置是Restarton-failure。它既能从异常崩溃中自动恢复又能避免在服务正常维护停止时被错误重启。关键配套配置为了让重启策略更可控强烈建议配合以下参数RestartSec指定重启前的等待时间。默认值为100ms建议设置为5s或10s。StartLimitBurstStartLimitIntervalSec限制单位时间内的重启次数防止“重启风暴”。例如StartLimitIntervalSec60和StartLimitBurst5表示在 60 秒内若重启超过 5 次则服务将进入失败状态停止重启。⚠️ 注意事项修改后重载修改.service文件后需执行sudo systemctl daemon-reload使改动生效。查看手册最完整的信息请参考man systemd.service手册页。总而言之Restarton-failure配合RestartSec和启动限制是守护长时间运行服务的标准且可靠的方案。RestartModeRestartMode是 systemd 中一个相对较新的配置项它与Restart协同工作主要目的是优化服务的自动重启流程尤其是在处理服务依赖时避免因临时故障引发不必要的连锁反应。它的核心思想是改变服务重启时的状态转换路径主要关注的是重启时是否要短暂地进入 失败 (failed) 或 未激活 (inactive) 状态。 主要取值目前RestartMode主要有以下几个取值取值行为引入版本/状态direct服务在自动重启时跳过failed 或 inactive 状态直接转换到 activating 状态。systemd v254quick与direct行为类似服务重启时不进入failed 状态。早期版本功能已被direct取代或合并debug当服务因失败而重启时将该单元的日志级别临时设置为debug并传递DEBUG_STARTUP1环境变量给服务自身-。较早版本normalRestartModenormal是 systemd 中RestartMode配置项的默认值。简单来说它代表了 systemd 处理服务重启的标准、常规行为。在这种模式下当服务需要重启时会完整地经历“停止 - 进入停止/失败状态 - 启动”的标准流程。normal模式的具体行为当服务因故需要重启时RestartModenormal会遵循以下标准流程进入停止/失败状态systemd 会先完全停止当前运行的服务实例并将该服务单元标记为inactive(未激活) 或failed(失败) 状态-。通知依赖单元这种状态的改变是“公开”的。所有依赖于该服务的其他单元例如使用Requires或Wants指令的target都会立即收到通知得知该服务已停止或失败-。执行重启在完成上述步骤后systemd 才会根据Restart策略重新启动该服务-。⚖️ 与direct模式的对比为了更清晰地理解normal有必要将其与direct模式进行对比。RestartModedirect是为优化服务重启流程、避免不必要的依赖单元失败而设计的-。两者的核心区别在于特性RestartModenormal(默认)RestartModedirect重启流程标准流程停止 - 进入失败状态 - 重启-优化流程跳过失败状态直接重启-对依赖单元的影响会立即通知依赖单元服务已失败-不会通知依赖单元避免其因短暂故障而失败-主要用途常规服务适用于大多数场景避免因oneshot类型服务的瞬时故障导致依赖它的target也一并失败版本要求默认行为通用systemd v254 或更高版本 为何需要 RestartMode默认情况下当一个设置了Restart的服务失败时systemd 的标准流程是服务进入 failed 状态。如果存在依赖它的单元例如使用Requires的target这些依赖单元会检测到my-service失败并随之进入 failed 状态。systemd 随后尝试重启my-service。但此时依赖my-service的target已经失败了即使my-service重启成功target也可能无法自动恢复。RestartModedirect就是为了解决这个问题。它让my-service在重启时不对外宣布自己的失败依赖它的单元也就不会收到错误信号从而保持运行或等待状态。 典型使用场景RestartModedirect最典型的场景是配合Typeoneshot使用。当一个oneshot服务失败并被Restarton-failure自动重启时可以避免依赖它的target也一并失败。RestartModedebug主要用于调试那些会频繁自动重启的服务。当服务启动失败时它可以自动输出更详细的调试信息帮助定位问题-。⚠️ 注意事项版本要求RestartModedirect需要systemd v254 或更高版本。在旧版本上设置该选项会被 systemd 忽略并产生一条无害的警告日志。并非万能RestartMode主要优化的是自动重启流程。对于通过systemctl restart发起的手动重启其行为可能不同。谨慎使用跳过 failed 状态虽然能避免依赖问题但也可能掩盖一些严重的、需要人工介入的故障。建议在充分理解其影响后再使用。 总结简单来说RestartModedirect是一个旨在让服务重启过程对系统其他部分更加“透明”的选项。它通过避免服务在自动重启时进入 “failed” 状态来防止因临时故障引发不必要的服务依赖雪崩。