🚀 第01章 · Nginx 架构与安装
安装/目录结构/工作模型
Nginx 架构与安装¶
这一章先把 Nginx 讲清楚:它到底是什么、为什么这么多站点用它的"事件驱动"模型、装好之后文件都放在哪、配置文件长什么样。学完你就明白,后面所有章节讲的虚拟主机、反向代理、负载均衡,都长在同一个骨架上。
为什么是 Nginx¶
传统 Web 服务器(如 Apache)是"进程/线程模型"——每一个请求独占一个进程或线程,连接多了内存和上下文切换成本迅速上升。Nginx 不一样,它天生为高并发、低内存而生,只处理两件事:
| 优势 | 说明 |
|---|---|
| 事件驱动异步 IO | 单个进程同时管理成千上万连接,不阻塞等待 |
| 反向代理/负载均衡 | 天然适合当"网关",转发请求到后端应用 |
| 静态资源极快 | 直接由 Nginx 发送文件,不经过后端语言 |
| 配置简单可读 | 层级化指令,一个配置文件就能看懂整个站点架构 |
这正是现实服务器里的分工:外层 Nginx 统一终止 TLS、转发请求到 127.0.0.1 上的各种后端服务。Nginx 在前面"站岗",真正的业务逻辑在后面的 Node/Python/Go/GitLab 里。
工作模型:master + worker¶
Nginx 启动后是一个 master 进程加若干 worker 进程:
master 进程 负责读取配置、管理 worker、优雅重启
├── worker 进程 (N 个) 真正处理请求,数量 = worker_processes
├── cache manager 进程 管理代理缓存(proxy_cache)
└── cache loader 进程 启动时把缓存目录加载进内存
打开本机的配置看一眼:
# worker 进程数量
grep -n 'worker_processes' /etc/nginx/nginx.conf
输出 worker_processes auto;,意思是让 Nginx 自动按 CPU 核数决定 worker 数量。auto 是省心的选择;也可以手动填一个数字,比如 4。
理解 worker 之间是平等的,都往同一个监听端口上 accept。所有 worker 共享配置,但各自独立处理连接。所以:想调并发上限,改
events块里的worker_connections,而不是疯狂加 worker。
事件驱动是怎么做到的¶
Nginx 用的是 OS 的 IO 多路复用机制(Linux 上是 epoll)。它把"等数据到达"这一步交给内核,内核一旦发现某个 socket 有数据可读/可写,就通知 Nginx。因此在等待网络 IO 时,Nginx 的 worker 不会被"卡住",而是继续处理别的请求。
events {
worker_connections 768; # 单个 worker 能同时处理的连接数
# multi_accept on; # 一次 accept 多个新连接(默认关,见注释)
}
注意
worker_connections是"每个 worker"的连接上限。Nginx 理论单机支撑的连接数 ≈worker_processes × worker_connections。而且每个连接默认还会占用文件描述符,记得检查系统的ulimit -n。
Ubuntu 上的目录结构¶
本机是 Ubuntu 24.04、通过 apt 安装的 nginx 1.24.0,文件分散在几个约定位置:
| 路径 | 作用 |
|---|---|
/etc/nginx/nginx.conf |
主配置文件,Nginx 从这里开始读 |
/etc/nginx/mime.types |
扩展名 → MIME 类型映射表 |
/etc/nginx/sites-available/ |
"可用的"站点配置,默认不加载 |
/etc/nginx/sites-enabled/ |
"启用的"站点配置,被 nginx.conf include |
/etc/nginx/conf.d/ |
通用片段,nginx.conf 无条件 include |
/var/log/nginx/ |
access_log / error_log 日志目录 |
/run/nginx.pid |
Nginx master 进程号(重载/停止信号用它) |
/usr/sbin/nginx |
Nginx 二进制本体 |
这里要特别说明 sites-available 和 sites-enabled 的关系:配置写在 available,再软链接到 enabled 才算启用。看本机的链接:
ls -l /etc/nginx/sites-enabled/
bangdream.xyz.conf -> /etc/nginx/sites-available/bangdream.xyz.conf
dsh.bangdream.xyz.conf -> /etc/nginx/sites-available/dsh.bangdream.xyz.conf
gitlab.bangdream.xyz.conf -> /etc/nginx/sites-available/gitlab.bangdream.xyz.conf
lovelive.top.conf -> /etc/nginx/sites-available/lovelive.top.conf
而 nginx.conf 里用 include /etc/nginx/sites-enabled/*; 把这些"已启用"的文件读进来。所以停用一个站点,把软链接删掉、再 nginx -s reload 即可,不必改配置文件本身。
安装与版本¶
# 更新索引后安装
sudo apt update
sudo apt install -y nginx
# 查看版本
nginx -v
# 查看编译参数(看它支持哪些模块)
nginx -V 2>&1 | tr ' ' '\n' | head
本机输出 nginx version: nginx/1.24.0 (Ubuntu)。nginx -V 会列出编译进的模块,比如 --with-http_ssl_module 说明支持 TLS,--with-stream 说明支持 TCP/UDP 四层代理。
易错
nginx -v只显示版本号,nginx -V(大写)才显示编译参数和模块列表。排错时想知道某个指令是否可用,先nginx -V看模块。
nginx.conf 的结构¶
配置文件是层级嵌套的:外层有一个全局 http {} 块,里面是 server {},再里面是 location {}。本机的主配置拆开看:
user www-data; # worker 进程以哪个用户运行(低权限更安全)
worker_processes auto; # 每核一个 worker
pid /run/nginx.pid; # master 进程号存放位置
error_log /var/log/nginx/error.log; # 全局错误日志
events {
worker_connections 768;
}
http {
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
sendfile on; # 静态文件由内核直接搬运,跳过用户态缓存
tcp_nopush on;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
gzip on;
include /etc/nginx/mime.types;
include /etc/nginx/conf.d/*.conf; # 通用片段
include /etc/nginx/sites-enabled/*; # 各虚拟主机配置
}
http {} 内的 map 是一段很实用的逻辑:它会根据请求头 Upgrade 的值,产出变量 $connection_upgrade。如果客户端请求了 WebSocket(Upgrade 非空),就取 upgrade;否则取 close。这个变量在后面 GitLab 反代时被用来设置 Connection 头。
理解
include是拼接文件的手段。把配置拆到sites-available、conf.d,是为了按站点和职责分离,而不是全部堆在一个大文件里。这也是你日后加站点的方式:新建一个*.conf,软链接进sites-enabled,重载即可。
启停与重载¶
Ubuntu 上用 systemd 管理(也直接支持 Nginx 自带的信号):
sudo systemctl enable --now nginx # 开机自启并启动
sudo systemctl restart nginx # 完全重启(会断开连接)
sudo systemctl reload nginx # 优雅重载,不中断现有连接
sudo systemctl status nginx # 查看运行状态
# 或者直接用 nginx 自带命令(依赖 master 进程)
sudo nginx -s quit # 优雅退出
sudo nginx -s stop # 立即退出
sudo nginx -s reload # 重新加载配置
易错
reload与restart有本质区别:restart会先停掉所有 worker、断开正在处理的连接;reload是"原地换血",旧 worker 处理完手头请求再退,新 worker 用新配置接管。线上改配置永远优先用 reload。
验证是否在跑¶
ps -ef | grep nginx | grep -v grep
# root master 进程
# www-data worker 进程...
ss -lntp | grep ':80 ' # 监听 80 端口
ss -lntp | grep ':443' # 监听 443 端口
看到 master 以 root、worker 以 www-data 运行,是正常的。master 需要 root 才能开 80/443 低端口,真正的处理交给降权后的 worker,这也是一种安全设计。
小结¶
这一章建立了阅读后续章节需要的全部背景:Nginx 是事件驱动的网关,由 master 加若干 worker 组成;配置按 http → server → location 嵌套;Ubuntu 下站点配置走 sites-available + sites-enabled 软链;改完配置用 reload 而不是 restart。下一章,我们把目光从全局骨架转向单个 server 块——虚拟主机是怎么区分不同域名的。