一、systemd服务配置
1.编辑nginx.service服务文件
vim /etc/systemd/system/nginx.service
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=network.target
[Service]
# 基础运行配置
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
User=nginx
Group=nginx
# 启动与停止
ExecStartPre=/usr/local/nginx/sbin/nginx -t -q -c /usr/local/nginx/conf/nginx.conf
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
# 核心限制与重启
LimitNOFILE=65535
Restart=on-failure
[Install]
WantedBy=multi-user.target
2.字段详解
Unit 模块 ------ 服务的元信息和依赖关系
| 字段 |
含义 |
Description=The NGINX HTTP and reverse proxy server |
服务的描述信息,执行 systemctl status nginx 时会显示 |
After=network.target |
指定启动顺序:Nginx 必须在网络服务启动之后再启动,确保网络已就绪 |
Service 模块 ------ 服务的核心行为定义
基础运行配置
| 字段 |
含义 |
Type=forking |
进程启动类型。Nginx 启动时会 fork 出子进程(master 进程),父进程随即退出。systemd 以此判断服务已启动成功 |
PIDFile=/usr/local/nginx/logs/nginx.pid |
指定主进程的 PID 文件路径。配合 Type=forking 使用,systemd 通过读取该文件来跟踪 Nginx 的主进程 |
User=nginx |
以 nginx 用户身份运行服务,避免使用 root 权限,提升安全性 |
Group=nginx |
以 nginx 用户组身份运行服务 |
启动与停止
| 字段 |
含义 |
ExecStartPre=/usr/local/nginx/sbin/nginx -t -q -c /usr/local/nginx/conf/nginx.conf |
启动前执行的命令。-t 测试配置文件语法,-q 静默模式。如果配置有错,服务将不会启动 |
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf |
正式启动命令。-c 指定配置文件路径 |
ExecReload=/usr/local/nginx/sbin/nginx -s reload |
重载配置命令。执行 systemctl reload nginx 时触发,Nginx 会平滑重载配置,不中断现有连接 |
ExecStop=/bin/kill -s QUIT $MAINPID |
停止服务命令。$MAINPID 是 systemd 自动替换为主进程 PID 的变量。QUIT 信号让 Nginx 优雅退出------等待所有请求处理完毕后再关闭 |
核心限制与重启
| 字段 |
含义 |
LimitNOFILE=65535 |
限制该服务最多可打开 65535 个文件描述符。Nginx 作为高并发 Web 服务器,每个连接占用一个文件描述符,此值决定了最大并发连接数的上限 |
Restart=on-failure |
自动重启策略。当服务异常退出(非 0 退出码、被信号杀死、超时等)时,systemd 会自动重启它。正常退出则不重启 |
Install 模块 ------ 服务的安装与开机自启
| 字段 |
含义 |
WantedBy=multi-user.target |
定义服务的安装目标。执行 systemctl enable nginx 时,systemd 会在 multi-user.target.wants/ 目录下创建一个指向该服务文件的符号链接,实现开机自启。multi-user.target 相当于传统 SysV 的运行级别 3(多用户命令行模式) |
2.启动nginx服务
# 2. 重新加载 systemd 配置
sudo systemctl daemon-reload
# 3. 启动服务
sudo systemctl start nginx
# 4. 设置开机自启
sudo systemctl enable nginx
# 5. 检查状态
sudo systemctl status nginx
二、systemd模块详解
1、Unit 模块 ------ 服务的元信息和依赖关系
| 字段 |
含义 |
示例 |
Description |
服务的简短描述 |
Description=The NGINX HTTP and reverse proxy server |
Documentation |
文档地址 |
Documentation=https://nginx.org/en/docs/ |
Requires |
强依赖,列出的 Unit 必须成功启动 |
Requires=network.target mysql.service |
Wants |
弱依赖,列出的 Unit 启动失败不影响本服务 |
Wants=network-online.target |
After |
本服务在列出的 Unit 之后启动 |
After=network.target remote-fs.target |
Before |
本服务在列出的 Unit 之前启动 |
Before=php-fpm.service |
BindsTo |
强绑定,列出的 Unit 退出时本服务也退出 |
BindsTo=postgresql.service |
PartOf |
列出的 Unit 停止时本服务也停止 |
PartOf=docker.service |
Conflicts |
冲突关系,不能同时运行 |
Conflicts=apache2.service |
OnFailure |
本服务失败时自动启动列出的 Unit |
OnFailure=notify-admin.service |
ConditionPathExists |
条件:文件存在才启动 |
ConditionPathExists=/etc/nginx/nginx.conf |
ConditionArchitecture |
条件:指定架构才启动 |
ConditionArchitecture=x86-64 |
2、Service 模块 ------ 服务的核心运行配置
该模块是 service 文件的核心,定义服务如何启动、停止、重启等行为。
1.进程类型
| 字段 |
含义 |
示例 |
Type=simple |
默认值,ExecStart 的进程即为主进程 |
Type=simple(适用于 Node.js、Python 等前台进程) |
Type=forking |
服务 fork 子进程后父进程退出 |
Type=forking(适用于 Nginx、Redis 等传统守护进程) |
Type=oneshot |
一次性任务,执行完即退出 |
Type=oneshot(适用于数据库迁移、初始化脚本) |
Type=notify |
服务启动完毕后主动通知 systemd |
Type=notify(适用于支持 sd_notify 的现代服务) |
2.生命周期控制
| 字段 |
含义 |
示例 |
ExecStart |
必填,启动服务时执行的命令 |
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf |
ExecStartPre |
启动前执行的命令 |
ExecStartPre=/usr/local/nginx/sbin/nginx -t -q |
ExecStartPost |
启动后执行的命令 |
ExecStartPost=/bin/echo "Nginx started on port 80" |
ExecReload |
重载配置时执行的命令 |
ExecReload=/usr/local/nginx/sbin/nginx -s reload |
ExecStop |
停止服务时执行的命令 |
ExecStop=/bin/kill -s QUIT $MAINPID |
ExecStopPost |
停止后执行的命令 |
ExecStopPost=/bin/rm -f /tmp/nginx.lock |
PIDFile |
主进程的 PID 文件路径 |
PIDFile=/usr/local/nginx/logs/nginx.pid |
TimeoutStartSec |
启动超时时间 |
TimeoutStartSec=30(30 秒内未启动成功则判定失败) |
TimeoutStopSec |
停止超时时间 |
TimeoutStopSec=5(5 秒后仍未停止则强制杀死) |
KillMode |
停止时的杀进程策略 |
KillMode=control-group(杀掉整个进程组) |
KillSignal |
停止时发送的信号 |
KillSignal=SIGQUIT(优雅退出) |
SendSIGKILL |
超时后是否强制 SIGKILL |
SendSIGKILL=no(不强制杀死,让进程自行退出) |
3.重启策略
| 字段 |
含义 |
示例 |
Restart=no |
不自动重启 |
Restart=no |
Restart=always |
总是重启 |
Restart=always |
Restart=on-failure |
异常退出时重启 |
Restart=on-failure |
RestartSec |
重启前等待秒数 |
RestartSec=3(等待 3 秒后再重启) |
StartLimitIntervalSec |
启动频率限制的时间窗口 |
StartLimitIntervalSec=60(60 秒内) |
StartLimitBurst |
时间窗口内最大启动次数 |
StartLimitBurst=5(最多启动 5 次,防止无限重启循环) |
4.用户与权限
| 字段 |
含义 |
示例 |
User |
以哪个用户身份运行 |
User=nginx |
Group |
以哪个用户组身份运行 |
Group=nginx |
DynamicUser |
使用动态分配的系统用户 |
DynamicUser=yes(服务停止后用户自动删除) |
SupplementaryGroups |
额外的附属用户组 |
SupplementaryGroups=www-data docker |
5.工作目录与环境
| 字段 |
含义 |
示例 |
WorkingDirectory |
服务的工作目录 |
WorkingDirectory=/var/www/app |
RootDirectory |
服务的根目录(chroot) |
RootDirectory=/var/chroot/nginx |
Environment |
设置环境变量 |
Environment=NODE_ENV=production PORT=3000 |
EnvironmentFile |
从文件加载环境变量 |
EnvironmentFile=/etc/default/nginx |
6.安全加固(Hardening)
| 字段 |
含义 |
示例 |
PrivateTmp |
分配独立的 /tmp |
PrivateTmp=true |
ProtectSystem=strict |
系统目录只读 |
ProtectSystem=strict |
ProtectHome |
保护用户家目录 |
ProtectHome=true |
NoNewPrivileges |
禁止获取新权限 |
NoNewPrivileges=true |
PrivateDevices |
分配独立的设备节点 |
PrivateDevices=true |
ReadOnlyPaths |
指定只读路径 |
ReadOnlyPaths=/etc/ssl /etc/nginx |
ReadWritePaths |
指定可读写路径 |
ReadWritePaths=/usr/local/nginx/logs |
InaccessiblePaths |
指定完全不可访问的路径 |
InaccessiblePaths=/root /etc/shadow |
CapabilityBoundingSet |
限制 Linux 能力 |
CapabilityBoundingSet=CAP_NET_BIND_SERVICE |
AmbientCapabilities |
设置环境能力 |
AmbientCapabilities=CAP_NET_BIND_SERVICE |
SystemCallArchitectures |
限制系统调用架构 |
SystemCallArchitectures=native |
MemoryDenyWriteExecute |
禁止可写可执行内存 |
MemoryDenyWriteExecute=true |
RestrictRealtime |
禁止实时调度策略 |
RestrictRealtime=true |
RestrictSUIDSGID |
禁止 SUID/SGID 文件 |
RestrictSUIDSGID=true |
7.资源限制
| 字段 |
含义 |
示例 |
LimitNOFILE |
最大打开文件描述符数 |
LimitNOFILE=65535 |
LimitNPROC |
最大进程数 |
LimitNPROC=65535 |
LimitCORE |
核心转储文件大小 |
LimitCORE=infinity(不限制) |
TasksMax |
最大线程数 |
TasksMax=100000 |
MemoryMax |
最大内存使用量 |
MemoryMax=2G |
CPUQuota |
CPU 配额限制 |
CPUQuota=50%(最多使用 50% 的 CPU) |
8,健壮性与调试
| 字段 |
含义 |
示例 |
WatchdogSec |
看门狗超时时间 |
WatchdogSec=30(30 秒内需发送心跳) |
StandardOutput |
标准输出重定向 |
StandardOutput=journal(输出到 journald) |
StandardError |
标准错误重定向 |
StandardError=journal |
SyslogIdentifier |
日志中的标识符 |
SyslogIdentifier=nginx |
3、Install 模块 ------ 安装与开机自启
| 字段 |
含义 |
示例 |
WantedBy |
启用时链接到哪个 Target |
WantedBy=multi-user.target(开机自启) |
RequiredBy |
强依赖链接到哪个 Target |
RequiredBy=graphical.target |
Alias |
服务的别名 |
Alias=www.service |
Also |
启用本服务时同时启用的其他服务 |
Also=nginx.socket |
4、完整示例:一个精简的 Nginx 服务文件
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=network.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
User=nginx
Group=nginx
ExecStartPre=/usr/local/nginx/sbin/nginx -t -q -c /usr/local/nginx/conf/nginx.conf
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
LimitNOFILE=65535
Restart=on-failure
[Install]
WantedBy=multi-user.target