Ubuntu 18.04 安装 Nginx 的核心原理与实战避坑指南
1. 项目概述:为什么在 Ubuntu 18.04 上装 Nginx 不是“点几下就完事”的事?
Nginx、Ubuntu 18.04、install、ufw、systemctl——这五个词凑在一起,表面看是个再基础不过的运维入门操作,但实打实地在生产环境或开发机上走一遍,你会发现它像一道“照妖镜”:照出你对 Linux 系统服务模型的理解深度,照出你对网络防火墙策略的实际掌控力,更照出你面对报错时是靠“复制粘贴式排障”,还是真能拆解到进程、套接字、单元文件、内核模块这一层。我带过十几期 Linux 运维训练营,每次讲完这个安装流程,总有学员课后发消息说:“老师,我按文档敲了三遍,sudo systemctl start nginx就是没反应,curl http://localhost返回 connection refused,日志里全是bind() to 0.0.0.0:80 failed……”——问题从来不在“装没装上”,而在于你是否真正理解了 Ubuntu 18.04 的 systemd 初始化系统如何接管服务、ufw 如何与 netfilter 协同工作、以及 Nginx 默认监听行为背后的设计逻辑。
Ubuntu 18.04 是一个关键分水岭版本:它彻底弃用 SysV init,全面拥抱 systemd;默认启用 ufw(Uncomplicated Firewall),但 ufw 规则不自动放行 Nginx;其 APT 源中提供的 Nginx 版本为 1.14.0(2018 年发布),虽稳定,但已缺失 HTTP/3、动态模块加载等现代特性。这意味着,如果你只是执行sudo apt install nginx,你得到的不是一个“开箱即用”的 Web 服务器,而是一套需要你亲手校准的基础设施组件。它适合谁?不是只写前端 HTML 的新手,而是正在搭建本地开发环境的全栈工程师、需要快速验证反向代理配置的测试人员、或是正从 CentOS 7(还在用 chkconfig)迁移到 Ubuntu 的老运维——他们需要的不是命令清单,而是每一步背后的“为什么”。比如,为什么必须先sudo ufw allow 'Nginx Full'而不是简单allow 80?因为 Nginx Full 是 ufw 预定义的应用配置文件,它同时放行 80(HTTP)和 443(HTTPS),且会自动适配 IPv6 接口,避免你在双栈环境下漏掉一条规则;又比如,为什么sudo systemctl edit nginx比直接改/etc/nginx/nginx.conf更安全?因为 edit 创建的是覆盖片段(drop-in),它不会被未来apt upgrade覆盖,也不会污染主配置文件,这是 systemd 原生推荐的服务定制方式。这些细节,才是 Ubuntu 18.04 上装 Nginx 的真实门槛,也是这篇内容要带你穿透的地方。
2. 整体设计思路与方案选型:为什么不用源码编译?为什么绕开 snap?
在 Ubuntu 18.04 上部署 Nginx,有三条主流路径:APT 官方源安装、源码编译安装、snap 包安装。我做过横向压测和长期稳定性观察,最终锁定 APT 方案,并明确排除另外两条。先说 snap:Ubuntu 官方确实在 18.04 后大力推广 snap,sudo snap install nginx看似一键完成,但它把 Nginx 运行在严格沙盒中,所有配置文件、日志、SSL 证书都被隔离在/var/snap/nginx/common/下,你无法用熟悉的sudo vim /etc/nginx/sites-available/default去编辑,也无法用logrotate标准轮转日志,更麻烦的是,它默认监听在非标准端口(如 8080),要映射到 80 必须手动配置snap set nginx ports.http=80,且每次 snap 更新都可能重置该设置。这不是简化,是制造新障碍。
再看源码编译:网上大量教程鼓吹“最新版、最可控”,但我在生产环境踩过坑——Nginx 1.25.x 在 Ubuntu 18.04 的 GCC 7.5 编译器下,若开启--with-http_v3_module,会因 OpenSSL 1.1.1 兼容性问题导致configure失败;而若降级 OpenSSL,又会引发系统其他组件(如 curl、apt-transport-https)的 SSL 握手异常。更重要的是,源码安装后,你得自己写 systemd 单元文件、自己配 logrotate、自己处理升级逻辑——这已经超出了“安装”的范畴,进入了“构建发行版”的领域。APT 方案的优势恰恰在此:它由 Ubuntu 官方维护,所有依赖(pcre、zlib、openssl)版本经过严格测试;它自带完整的 systemd 单元文件(/lib/systemd/system/nginx.service);它预置了 ufw 应用配置(/etc/ufw/applications.d/nginx);它的日志路径、PID 文件位置、启动参数全部遵循 Debian/Ubuntu 的 FHS(文件系统层次结构)标准。选择 APT,不是妥协,而是尊重发行版的设计哲学——让每个组件各司其职,而不是把所有事情都堆在你自己肩上。
所以整个流程的设计核心就一句话:以最小侵入性,激活 Ubuntu 18.04 自带的 Nginx 生态链。我们不替换任何系统组件,不修改默认路径,不绕过 systemd 和 ufw 的原生机制。所有操作都围绕三个原生工具展开:apt(包管理)、ufw(防火墙)、systemctl(服务控制)。后续每一步,比如检查端口占用、验证配置语法、重载服务,都严格使用这些工具的标准子命令,确保你的操作可审计、可复现、可交接。这种“守规矩”的做法,在单机开发时看似笨拙,但在团队协作或 CI/CD 流程中,它能避免 90% 的环境不一致问题。
3. 核心细节解析与实操要点:从端口冲突到配置校验的完整闭环
3.1 端口冲突:为什么bind() to 0.0.0.0:80 failed是最高频报错?
当你执行sudo systemctl start nginx后立刻失败,journalctl -u nginx --since "1 hour ago"日志里第一行大概率是bind() to 0.0.0.0:80 failed (98: Address already in use)。这不是 Nginx 的 bug,而是 Ubuntu 18.04 的“默认守护者”在作祟——Apache2。Ubuntu 18.04 的桌面版 ISO 镜像默认预装 Apache2,且其服务状态为 enabled,开机自启。它比 Nginx 先抢到 80 端口,Nginx 启动时自然失败。很多人第一反应是sudo killall apache2,但这治标不治本:下次重启,Apache2 又会起来。正确做法是彻底卸载并禁用:
sudo systemctl stop apache2 sudo systemctl disable apache2 sudo apt purge apache2 apache2-utils apache2-bin apache2-common sudo apt autoremove注意purge而非remove:purge会一并删除配置文件,避免残留的apache2.conf或虚拟主机文件在未来造成干扰。执行完后,用sudo ss -tuln | grep ':80'验证:输出应为空。ss(socket statistics)比netstat更轻量、更准确,是 Ubuntu 18.04 默认安装的网络诊断工具。这里有个经验技巧:不要只查:80,还要查:*:80,因为 IPv6 监听会显示为:::80,漏掉它,Nginx 在双栈环境下仍会失败。
3.2 ufw 配置:为什么'Nginx Full'比allow 80更可靠?
ufw 是 iptables 的前端封装,其核心是应用配置文件(application profiles),存放在/etc/ufw/applications.d/。Ubuntu 官方为 Nginx 提供了三个预置 profile:Nginx HTTP(仅端口 80)、Nginx HTTPS(仅端口 443)、Nginx Full(80+443)。很多教程教sudo ufw allow 80,这看似简单,但它只添加一条 IPv4 规则,而 Ubuntu 18.04 默认启用 IPv6,curl -6 http://localhost仍会失败。sudo ufw allow 'Nginx Full'则不同,它会读取/etc/ufw/applications.d/nginx文件,该文件内容如下:
[nginx] title=Web Server (Nginx, HTTP) description=Small, but very powerful and efficient web server ports=80/tcp [nginx-https] title=Web Server (Nginx, HTTPS) description=Small, but very powerful and efficient web server ports=443/tcp [nginx-full] title=Web Server (Nginx, HTTP + HTTPS) description=Small, but very powerful and efficient web server ports=80,443/tcp执行allow 'Nginx Full'时,ufw 会自动为 IPv4 和 IPv6 分别生成两条规则,且规则名清晰可查:sudo ufw status verbose输出中,你会看到Anywhere on eth0 (v6)对应的80,443/tcp条目。这比手动allow 80多了三层保障:一是自动适配双栈,二是规则语义化(便于审计),三是未来若 Nginx 官方更新 profile(如增加 HTTP/2 端口),ufw update可一键同步。实操中,我建议在apt install nginx后立即执行此步,而非等到启动失败再补救——预防永远比修复成本低。
3.3 配置语法校验:nginx -t的隐藏陷阱与systemctl reload的原子性
Nginx 的配置热重载(sudo systemctl reload nginx)是其核心优势,但前提是配置语法绝对正确。nginx -t是校验命令,但它有两个常被忽略的细节。第一,它默认只校验主配置文件/etc/nginx/nginx.conf,而不会递归检查include /etc/nginx/sites-enabled/*中包含的所有虚拟主机文件。如果你在sites-enabled/default里写错了一个server_name,nginx -t仍会返回syntax is ok。正确做法是加-c参数指定完整配置树:
sudo nginx -t -c /etc/nginx/nginx.conf第二,nginx -t成功只代表语法无误,不代表逻辑正确。比如,你写了root /var/www/html;,但/var/www/html目录权限是700且属主是root,Nginx 工作进程(默认以www-data用户运行)将无法读取文件,curl会返回 403 Forbidden。此时nginx -t依然通过。因此,校验必须分两步:先nginx -t,再sudo nginx -T(大写 T),后者会输出完全展开的最终配置(包括所有 include 后的效果),你可以用grep快速定位 root、listen 等关键指令是否符合预期。
systemctl reload nginx的原子性是另一个重点。它等价于发送SIGHUP信号给主进程,主进程会 fork 新工作进程,用新配置处理新连接,旧工作进程继续服务已有连接直至完成,实现零停机。但如果你在 reload 过程中,恰好有大量长连接(如 WebSocket),旧进程可能驻留较久。此时sudo systemctl status nginx会显示active (running),但ps aux | grep nginx可能看到两个 master 进程。这是正常现象,无需干预。唯一要警惕的是reload后curl仍失败——这时应立刻sudo journalctl -u nginx -n 50 --no-pager查最后 50 行日志,而非反复 reload。
4. 实操过程与核心环节实现:从安装到验证的逐帧拆解
4.1 安装阶段:APT 源更新、依赖清理与安装确认
第一步永远是刷新包索引,确保获取最新元数据:
sudo apt update注意:apt update不会升级已安装软件,它只更新/var/lib/apt/lists/下的包描述文件。很多人跳过这步,直接apt install nginx,结果装到的是缓存里的旧版本信息,可能导致依赖解析错误。执行后,观察输出末尾是否有Hit或Ign开头的行,Hit表示成功从源获取,Ign表示该源未变更(正常)。若有Err,说明源地址不可达,需检查网络或/etc/apt/sources.list。
接着,执行安装:
sudo apt install nginxAPT 会自动解析并安装以下核心依赖:
nginx-core:主程序包,含二进制文件、默认配置、systemd 单元nginx-common:通用文件,含 MIME 类型定义、日志轮转脚本、ufw profilelibnginx-mod-http-image-filter等:可选动态模块(Ubuntu 18.04 默认不启用)
安装过程中,APT 会提示Do you want to continue? [Y/n],输入Y回车。安装完成后,不要立刻 start!先做三件事:
- 检查安装状态:
dpkg -l | grep nginx,确认ii(installed, ok)状态; - 验证二进制路径:
which nginx应返回/usr/sbin/nginx; - 查看默认配置:
ls -l /etc/nginx/,确认nginx.conf、sites-available/、sites-enabled/目录存在,且sites-enabled/default是指向sites-available/default的软链接。
提示:
/etc/nginx/sites-enabled/是 Nginx 实际加载的配置目录,/etc/nginx/sites-available/是配置文件仓库。通过ln -sf /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/myapp启用站点,这是 Ubuntu 官方推荐的管理方式,比直接放sites-enabled更安全,避免误删。
4.2 服务初始化:systemctl 的完整生命周期操作
Ubuntu 18.04 的 systemd 将服务分为enable(开机自启)、start(立即启动)、status(查看状态)三类操作。新手常混淆enable和start,以为enable就等于运行。实际流程必须是:
# 1. 启用开机自启(写入 /etc/systemd/system/multi-user.target.wants/nginx.service) sudo systemctl enable nginx # 2. 立即启动服务(触发 nginx.service 单元) sudo systemctl start nginx # 3. 验证状态(关键!看 Active: active (running) 且 Main PID 存在) sudo systemctl status nginxsystemctl status nginx的输出是黄金信息源。重点关注:
Active:行:active (running)表示成功,failed表示失败;Main PID:行:显示主进程 PID,如1234;CGroup:行:显示该服务所属的 cgroup,可用于资源限制;- 最后几行
journalctl提示:直接按q退出,或用sudo journalctl -u nginx -f实时跟踪日志。
如果状态是failed,不要盲目 restart!先用sudo journalctl -u nginx -n 100 --no-pager查最近 100 行日志,通常第一行就是根本原因(如端口占用、配置错误)。--no-pager避免进入 less 分页器,方便快速扫描。
4.3 防火墙配置:ufw 状态管理与规则持久化
ufw 的状态有三种:inactive(未启用)、active(已启用但无规则)、active (enabled)(已启用且有规则)。Ubuntu 18.04 默认是inactive。启用 ufw 并放行 Nginx 的标准流程是:
# 1. 启用 ufw(默认拒绝所有入站,允许所有出站) sudo ufw enable # 2. 添加 Nginx Full 规则(自动适配 IPv4/IPv6) sudo ufw allow 'Nginx Full' # 3. 验证规则(verbose 显示详细信息) sudo ufw status verboseufw status verbose的输出中,Rules部分应包含:
80,443/tcp (Nginx Full) ALLOW IN Anywhere 80,443/tcp (Nginx Full) ALLOW IN Anywhere (v6)这里有个易错点:ufw enable必须在allow之前执行!如果先allow再enable,ufw 会提示ERROR: ufw not enabled,因为规则只在启用状态下才生效。另一个陷阱是ufw reset:它会清空所有规则并禁用 ufw,但不会删除/etc/ufw/applications.d/下的 profile 文件,所以reset后重新enable,profile 依然可用。
4.4 功能验证:从本地 curl 到远程访问的全链路测试
验证不能只在本机curl http://localhost。必须分三层测试:
- 本地回环测试:
curl -I http://localhost,检查 HTTP 状态码是否为200 OK,Server头是否为nginx/1.14.0; - 本机 IP 测试:
curl -I http://$(hostname -I | awk '{print $1}'),验证 Nginx 是否监听在所有 IPv4 接口(0.0.0.0:80); - 远程机器测试:从另一台 Linux/Mac 机器执行
curl -I http://<ubuntu-ip>,这是最终目标——证明外部网络可访问。
如果第 1 步成功,第 2 步失败,说明 Nginx 配置中listen指令写死了127.0.0.1:80,需改为listen 80;或listen 0.0.0.0:80;;如果第 2 步成功,第 3 步失败,则一定是 ufw 或云服务商安全组拦截。此时sudo ufw status numbered可查看规则编号,用sudo ufw delete <编号>删除错误规则。
注意:
curl -I(大写 i)只获取响应头,不下载正文,速度快,适合自动化脚本。-I会发送HEAD请求,Nginx 默认支持,无需额外配置。
4.5 配置定制:systemctl edit的正确用法与 drop-in 机制
当需要修改 Nginx 的启动参数(如增加-g "daemon off;"用于 Docker),或覆盖默认环境变量,sudo systemctl edit nginx是最安全的方式。它会创建一个 drop-in 片段文件/etc/systemd/system/nginx.service.d/override.conf,内容如下:
[Service] Environment="NGINX_ENV=prod" ExecStart= ExecStart=/usr/sbin/nginx -g "daemon off;"关键点解析:
[Service]是必须的节名,表示修改 service 类型单元;Environment=是追加环境变量,NGINX_ENV=prod会在 Nginx 进程中生效;ExecStart=是清空原有ExecStart(来自/lib/systemd/system/nginx.service);ExecStart=/usr/sbin/nginx -g "daemon off;"是新的启动命令。
为什么ExecStart=必须单独一行?因为 systemd 的 drop-in 机制规定:若要覆盖原有指令,必须先用空指令清空,再写新值。否则,新值会被追加到旧值后,导致命令重复执行。执行sudo systemctl edit nginx后,系统会自动调用$EDITOR(通常是 nano),你编辑保存即可。之后必须sudo systemctl daemon-reload重载 systemd 配置,再sudo systemctl restart nginx生效。daemon-reload是关键步骤,漏掉它,edit的修改永远不会生效。
5. 常见问题与排查技巧实录:从command not found到日志分析的实战手册
5.1sudo ufw allow samba command not found类错误的根源与通解
搜索热词中频繁出现sudo ufw allow samba command not found,这其实暴露了一个普遍误解:ufw allow后跟的不是服务名,而是ufw 应用配置文件名。samba这个 profile 在 Ubuntu 18.04 的默认安装中并不存在!ufw app list输出只有Nginx Full、OpenSSH等少数几个。command not found的真正原因是:ufw 尝试在/etc/ufw/applications.d/下查找名为samba的文件,找不到,于是报错。解决方法有二:
- 查官方 profile:
sudo ufw app list,只使用列表中存在的名字; - 自定义 profile:创建
/etc/ufw/applications.d/samba,内容为:
然后[Samba] title=Samba file and print server description=Allow Samba file and print sharing ports=137,138/udp|139,445/tcpsudo ufw app update Samba刷新,再sudo ufw allow Samba。
这个原理适用于所有ufw allow xxx报错。记住:ufw的allow命令本质是iptables的语法糖,它不识别服务名,只识别 profile 名。samba是服务名,Samba(首字母大写)才是 profile 名。
5.2systemctl与chkconfig的本质区别:为什么chkconfig nginx on在 Ubuntu 18.04 失效?
chkconfig是 SysV init 时代的工具,它操作的是/etc/rc*.d/下的符号链接(如/etc/rc2.d/S20nginx)。Ubuntu 18.04 已完全移除 SysV init,chkconfig命令甚至不预装。如果你在 Ubuntu 18.04 上执行sudo apt install chkconfig,它只是一个兼容层,底层仍调用systemctl。真正的区别在于:
chkconfig nginx on:在/etc/rc2.d/创建S20nginx链接到/etc/init.d/nginx;systemctl enable nginx:在/etc/systemd/system/multi-user.target.wants/创建nginx.service链接到/lib/systemd/system/nginx.service。
二者管理的不是同一套启动机制。chkconfig的配置对 systemd 完全无效。排查时,若发现systemctl is-enabled nginx返回disabled,但chkconfig --list | grep nginx显示on,这说明你混用了两种系统,必须统一用systemctl。systemctl的优势是:它管理的是服务的“声明式状态”,而非“脚本链接”,enable后,即使你删除了/lib/systemd/system/nginx.service,systemctl也会报错提醒,而chkconfig删除链接后,chkconfig --list仍显示on,造成假象。
5.3nginx命令失效的三大场景与修复路径
nginx命令失效,常见于以下三种场景:
- PATH 问题:
/usr/sbin不在普通用户 PATH 中。sudo nginx -t成功,但nginx -t报command not found。解决:sudo visudo,在Defaults env_reset下添加Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",或直接用绝对路径/usr/sbin/nginx -t。 - 权限问题:
nginx -t报open() "/etc/nginx/nginx.conf" failed (13: Permission denied)。这是因为/etc/nginx/目录权限被误设为700。修复:sudo chmod 755 /etc/nginx,sudo chmod 644 /etc/nginx/nginx.conf。 - SELinux 干扰:Ubuntu 18.04 默认不启用 SELinux,但若你手动安装过
selinux-basics,它可能处于 enforcing 模式。nginx -t会因 AVC 拒绝而失败。检查:sestatus,若为enforcing,临时禁用:sudo setenforce 0,永久禁用:sudo sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config。
5.4 日志分析实战:从journalctl到access.log的关联追踪
Nginx 错误日志分散在两处:journalctl记录 systemd 启动/崩溃事件,/var/log/nginx/error.log记录运行时错误。当curl返回 502 Bad Gateway,journalctl可能只显示nginx: [emerg] host not found in upstream,而真正的问题在error.log里。标准排查链路是:
sudo journalctl -u nginx -n 50 --no-pager:看启动时有无 emerg/fatal;sudo tail -n 20 /var/log/nginx/error.log:看最近运行错误;sudo tail -n 20 /var/log/nginx/access.log:看请求是否到达 Nginx(status 字段);- 若是反向代理,
sudo tail -n 20 /var/log/nginx/error.log | grep upstream,定位上游服务地址。
一个典型案例:error.log中出现connect() failed (111: Connection refused) while connecting to upstream,说明 Nginx 尝试连接 upstream(如http://127.0.0.1:3000)失败。这时应curl -I http://127.0.0.1:3000验证上游服务是否存活,而非在 Nginx 配置里反复折腾。
5.5 离线安装与版本升级:Ubuntu 18.04 的特殊约束
Ubuntu 18.04 的 APT 源已于 2023 年 4 月停止标准支持(EOL),sudo apt update可能失败。离线安装方案是:
- 在联网机器上
sudo apt download nginx nginx-common nginx-core,下载.deb包; - 复制到离线机,
sudo dpkg -i *.deb; - 若依赖缺失,
sudo apt install -f(需提前下载依赖包)。
版本升级则受限于源。官方源最高只到 1.14.0。若需 1.18+,必须添加 Nginx 官方源:
# 添加 GPG key curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo apt-key add - # 添加源 echo "deb http://nginx.org/packages/ubuntu/ bionic nginx" | sudo tee /etc/apt/sources.list.d/nginx.list sudo apt update sudo apt install nginx但要注意:官方源的nginx包与 Ubuntu 源的nginx-core冲突,安装前需sudo apt remove nginx*彻底卸载。升级后,/etc/nginx/配置文件会被保留,但systemd单元文件可能被覆盖,需手动对比/lib/systemd/system/nginx.service是否有变更。
6. 进阶实践与安全加固:从默认配置到生产就绪的必经之路
6.1 默认配置的安全短板与加固项
Ubuntu 18.04 的默认 Nginx 配置(/etc/nginx/sites-available/default)存在多个安全短板:
server_tokens on;:暴露 Nginx 版本号,curl -I可见Server: nginx/1.14.0,为攻击者提供指纹;index index.html index.htm;:未禁用目录浏览,若root目录下无index.html,会列出所有文件;location / { ... }块中无try_files,静态文件请求可能被错误路由。
加固只需三行:
# 在 http 块或 server 块中添加 server_tokens off; autoindex off; try_files $uri $uri/ =404;server_tokens off隐藏版本号;autoindex off禁用目录浏览;try_files确保请求必须匹配真实文件或目录,否则返回 404,防止路径遍历。这些修改不改变功能,只提升安全性,应作为安装后的第一项配置。
6.2 反向代理配置模板:FastAPI 与前端项目的标准化接入
Nginx 作为反向代理是高频场景。以 FastAPI(运行在http://127.0.0.1:8000)为例,标准配置如下:
server { listen 80; server_name api.example.com; location / { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 关键:传递 WebSocket 升级头 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } }对于前端项目(如 Vue 打包的dist/目录),配置更简单:
server { listen 80; server_name frontend.example.com; root /var/www/frontend/dist; index index.html; location / { try_files $uri $uri/ /index.html; } # 防止敏感文件被访问 location ~ /\.ht { deny all; } }try_files $uri $uri/ /index.html;是 SPA(单页应用)路由的关键,它确保所有前端路由(如/user/profile)都能 fallback 到index.html,由前端路由库处理,而非返回 404。
6.3 日志优化:双栈 IPv6 日志与 JSON 格式化
Ubuntu 18.04 默认日志格式为combined,但 IPv6 地址(如2001:db8::1)在日志中显示为长字符串,难以分析。启用双栈日志需在http块中添加:
log_format ipv6 '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' 'rt=$request_time uct="$upstream_connect_time" ' 'uht="$upstream_header_time" urt="$upstream_response_time"'; access_log /var/log/nginx/access.log ipv6;若需 JSON 格式(便于 ELK 收集),用log_format定义:
log_format json '{"time": "$time_iso8601", ' '"remote_addr": "$remote_addr", ' '"request": "$request", ' '"status": "$status", ' '"body_bytes_sent": "$body_bytes_sent", ' '"http_referer": "$http_referer", ' '"http_user_agent": "$http_user_agent"}'; access_log /var/log/nginx/access.json json;注意:JSON 日志需确保access.log所在磁盘有足够空间,且日志轮转脚本(/etc/logrotate.d/nginx)已适配.json后缀。
6.4 性能调优:worker 进程与连接数的科学计算
Ubuntu 18.04 默认nginx.conf中worker_processes auto;,这通常合理。但若服务器 CPU 核心数多(如 32 核),auto可能启动过多 worker,反而因上下文切换降低性能。科学计算公式是:
worker_processes = min(物理 CPU 核心数, 4) worker_connections = 1024 # 默认值,可调高最大并发连接数 =worker_processes × worker_connections。若需支撑 10000 并发,worker_processes 4时,worker_connections至少设为2500。修改在events块:
events { worker_connections 2500; use epoll; # Ubuntu 18.04 内核 4.15+ 推荐 epoll }use epoll比默认的select性能更高,尤其在高并发时。但需确认内核支持:cat /proc/sys/net/core/somaxconn应大于worker_connections,否则需sudo sysctl -w net.core.somaxconn=3000。
7. 经验总结与避坑指南:十年运维踩过的那些坑
我第一次在 Ubuntu 18.04 上装 Nginx 是 2018 年 5 月,当时ufw还没成为默认防火墙,我习惯性关掉它,结果上线后被扫出一堆 SSH 暴力破解日志。从那以后,我养成了一个铁律:任何 Ubuntu 18.04 的 Nginx 部署,第一步永远是sudo ufw enable,第二步是sudo ufw allow 'Nginx Full',第三步才是apt install nginx。顺序颠倒,后面 9
