一、Nginx 安装(以 Ubuntu 为主,兼容主流系统)
1.1 Ubuntu 系统安装(推荐 APT 方式,稳定易维护)
1.1.1 基础安装(官方稳定版)
bash
运行
# 1. 更新软件源
sudo apt update
# 2. 安装 Nginx(Ubuntu 默认源为稳定版)
sudo apt install nginx -y
# 3. 验证安装(可选,安装后自动启动)
nginx -v # 输出版本号即安装成功,如 nginx/1.18.0 (Ubuntu)
1.1.2 编译安装(自定义功能,进阶场景)
适用于需要自定义模块(如 SSL、缓存)的场景:
bash
运行
# 1. 安装编译依赖
sudo apt install gcc make libpcre3 libpcre3-dev zlib1g zlib1g-dev libssl-dev -y
# 2. 下载源码(替换为最新版本)
wget http://nginx.org/download/nginx-1.24.0.tar.gz
tar -zxvf nginx-1.24.0.tar.gz
cd nginx-1.24.0
# 3. 配置编译参数(自定义安装路径+模块)
./configure --prefix=/usr/local/nginx
--with-http_ssl_module
--with-http_gzip_static_module
--with-http_stub_status_module
# 4. 编译并安装
make && sudo make install
# 5. 创建软链接(方便全局调用)
sudo ln -s /usr/local/nginx/sbin/nginx /usr/bin/nginx
1.2 其他系统安装(简要补充)
|
系统 |
安装命令 |
|
CentOS 7/8 |
sudo yum install nginx -y(需先配置 EPEL 源) |
|
Windows |
下载官网 zip 包( |
|
Docker |
docker run -d –name nginx -p 80:80 nginx:latest |
1.3 安装验证
bash
运行
# 1. 检查版本
nginx -v
# 2. 检查配置语法(核心!避免安装后配置错误)
nginx -t
# 3. 访问默认页面(Ubuntu)
curl http://localhost # 输出 Nginx 默认欢迎页 HTML 即成功
二、使用 systemctl 管理 Nginx 服务(Ubuntu 16.04+ 主流方案)
2.1 核心前提:systemd 服务文件
- APT 安装的 Nginx 自动生成服务文件:/lib/systemd/system/nginx.service
- 编译安装的 Nginx 需手动创建服务文件(见 2.5 节)
2.2 常用 systemctl 命令(高频操作)
|
操作目标 |
命令 |
说明 |
|
启动服务 |
sudo systemctl start nginx |
启动 Nginx 服务 |
|
停止服务 |
sudo systemctl stop nginx |
停止 Nginx 服务(会中断现有连接) |
|
重启服务 |
sudo systemctl restart nginx |
重启服务(配置修改涉及核心参数时用,如 worker_processes) |
|
重载配置 |
sudo systemctl reload nginx |
重载配置(不中断现有连接,修改 server/location 后优先用) |
|
查看服务状态 |
sudo systemctl status nginx |
查看运行状态(Active: active (running) 为正常) |
|
开机自启 |
sudo systemctl enable nginx |
配置开机自动运行 |
|
关闭开机自启 |
sudo systemctl disable nginx |
撤销开机自动运行 |
|
查看自启状态 |
sudo systemctl is-enabled nginx |
输出 enabled/disabled 表明是否自启 |
|
刷新服务配置 |
sudo systemctl daemon-reload |
修改 service 文件后需执行,让 systemd 识别修改 |
2.3 开机自启配置(关键!生产环境必配)
bash
运行
# 1. 开启开机自启
sudo systemctl enable nginx
# 成功输出:Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /lib/systemd/system/nginx.service.
# 2. 验证自启状态
sudo systemctl is-enabled nginx # 输出 enabled
# 3. 重启系统验证(可选)
sudo reboot
sudo systemctl status nginx # 显示 active (running) 即自启成功
2.4 服务日志查看(排查问题核心)
bash
运行
# 1. 查看 Nginx 系统日志(systemd 管理日志)
journalctl -u nginx -xe # -xe 显示详细错误信息
# 2. 查看 Nginx 访问/错误日志(默认路径)
tail -f /var/log/nginx/access.log # 实时查看访问日志
tail -f /var/log/nginx/error.log # 实时查看错误日志
2.5 手动编译安装 Nginx 的 systemd 服务配置
编译安装的 Nginx 无默认 service 文件,需手动创建:
bash
运行
# 1. 创建服务文件
sudo vim /etc/systemd/system/nginx.service
写入以下内容(根据编译安装路径调整):
ini
[Unit]
Description=nginx - High Performance Web Server
Documentation=http://nginx.org/en/docs/
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
# 编译安装的 Nginx 可执行文件路径
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
# 停止命令
ExecStop=/usr/local/nginx/sbin/nginx -s stop
# 重载配置
ExecReload=/usr/local/nginx/sbin/nginx -s reload
# 强制停止
ExecStop=/bin/kill -s QUIT $MAINPID
# PID 文件路径(编译安装默认路径)
PIDFile=/usr/local/nginx/logs/nginx.pid
PrivateTmp=true
# 服务失败时自动重启
Restart=on-failure
[Install]
WantedBy=multi-user.target
生效配置:
bash
运行
sudo systemctl daemon-reload # 刷新配置
sudo systemctl enable nginx # 开启自启
sudo systemctl start nginx # 启动服务
三、Nginx 解决前后端分离跨域问题
3.1 跨域本质:浏览器同源策略
浏览器要求请求的「协议、域名、端口」三者完全一致(同源),否则拦截响应。例如:
- 前端:http://localhost:8080 → 后端:http://localhost:3000/api(端口不同)→ 跨域报错。
3.2 核心方案 1:反向代理(生产最优解,无侵入后端)
3.2.1 配置原理
前端请求「同域的 Nginx」(如 http://localhost/api),Nginx 转发请求到后端服务;对浏览器而言是同域请求,无跨域问题。
3.2.2 完整配置示例(托管前端 + 代理 API)
nginx
# 全局配置(Ubuntu 路径:/etc/nginx/nginx.conf 或 /etc/nginx/conf.d/cors.conf)
http {
# 定义后端服务集群(单实例也可配置)
upstream backend_api {
server 192.168.1.100:8080; # 后端 API 地址
# 多实例:server 192.168.1.101:8080;
}
server {
listen 80;
server_name localhost; # 前端访问的域名/IP
# 1. 托管前端静态资源(Vue/React 打包后的 dist 目录)
root /usr/share/nginx/html;
index index.html;
# 2. 反向代理后端 API(核心:解决跨域)
location /api/ {
proxy_pass http://backend_api/; # 转发到后端服务(末尾/关键!)
# 传递客户端真实信息给后端
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_connect_timeout 60s;
proxy_read_timeout 60s;
}
# 3. 解决 SPA 前端路由刷新 404(Vue/React Router history 模式)
location / {
try_files $uri $uri/ /index.html;
}
}
}
3.2.3 关键配置项解释
|
配置项 |
作用 |
|
root /usr/share/nginx/html |
指定前端静态资源目录,Nginx 自动托管 HTML/CSS/JS |
|
location /api/ |
匹配所有 /api 开头的请求(前端 API 路径) |
|
proxy_pass http://backend_api/ |
转发请求到后端;末尾 / 需加:前端 /api/user → 后端 /user(否则为 /api/user) |
|
try_files |
SPA 刷新时优先找静态文件,找不到返回 index.html,避免 404 |
3.3 核心方案 2:CORS 响应头配置(备选,后端无法修改时)
3.3.1 配置原理
Nginx 在转发响应时添加 CORS 头,告知浏览器 “允许该源跨域访问”,需处理「简单请求」和「预检请求(OPTIONS)」。
3.3.2 完整配置示例
nginx
server {
listen 80;
server_name api.example.com; # 后端 API 域名(前端直接请求该域名)
location / {
# 允许的跨域源(生产环境指定具体域名,如 http://www.example.com)
add_header Access-Control-Allow-Origin *;
# 允许的请求方法
add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';
# 允许的请求头(含自定义头,如 token)
add_header Access-Control-Allow-Headers 'Content-Type, Authorization, Token';
# 预检请求缓存时间(避免频繁发 OPTIONS)
add_header Access-Control-Max-Age 3600;
# 处理预检请求(OPTIONS)
if ($request_method = 'OPTIONS') {
return 204; # 无需返回内容,204 即可
}
# 转发到后端服务
proxy_pass http://192.168.1.100:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
3.3.3 跨域携带 Cookie 配置(需前后端配合)
- Nginx 配置(Origin 必须指定具体域名,不能用 *):
- nginx
- location /api/ { add_header Access-Control-Allow-Origin http://www.example.com; # 前端域名 add_header Access-Control-Allow-Credentials true; # 允许携带 Cookie proxy_pass http://backend_api/; }
- 前端配置(Axios 示例):
- javascript
- 运行
- axios({ url: '/api/user', method: 'GET', withCredentials: true // 开启携带 Cookie })
3.3.4 允许多域名跨域
nginx
# 定义允许的域名列表
map $http_origin $allow_origin {
~^http://www.example.com$ http://www.example.com;
~^http://m.example.com$ http://m.example.com;
default ""; # 其他域名拒绝
}
server {
listen 80;
server_name api.example.com;
location /api/ {
add_header Access-Control-Allow-Origin $allow_origin;
add_header Access-Control-Allow-Credentials true;
add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';
if ($request_method = 'OPTIONS') {
return 204;
}
proxy_pass http://backend_api/;
}
}
3.4 开发环境 vs 生产环境跨域方案对比
|
场景 |
推荐方案 |
缘由 |
|
开发环境 |
前端脚手架代理(Vue/Vite/React) |
无需部署 Nginx,配置简单(devServer.proxy),调试高效 |
|
生产环境 |
Nginx 反向代理 |
无侵入后端、兼顾静态资源托管 / 负载均衡,安全稳定 |
3.5 跨域配置避坑指南
- proxy_pass 末尾 / 易错:location /api/ + proxy_pass http://backend/ → 转发 /api/user 为 /user;无 / 则为 /api/user。
- 预检请求未处理:非简单请求(PUT/DELETE)先发 OPTIONS,需配置 if ($request_method = 'OPTIONS') { return 204; }。
- Cookie 跨域报错:Access-Control-Allow-Origin 用 * 且开启 withCredentials,需改为具体域名。
- 配置不生效:先执行 nginx -t 检查语法,再 systemctl reload nginx 重载,最后清浏览器缓存。
四、Nginx 实现后端服务负载均衡
4.1 负载均衡核心原理
通过 upstream 模块定义后端服务集群,Nginx 将前端请求分发到不同后端实例,提升吞吐量和可用性。
4.2 upstream 模块基础配置
nginx
http {
# 定义后端集群(名称自定义,如 backend_server)
upstream backend_server {
# 后端实例配置(IP:端口)
server 192.168.1.10:8080 weight=1; # weight=权重,默认1
server 192.168.1.11:8080 weight=2; # 权重2,接收2/3的请求
server 192.168.1.12:8080 backup; # 备用节点,主节点故障时启用
server 192.168.1.13:8080 down; # 下线节点,不接收请求
}
server {
listen 80;
server_name localhost;
# 代理到后端集群
location /api/ {
proxy_pass http://backend_server/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
4.3 常用负载均衡策略
|
策略 |
配置方式 |
适用场景 |
|
轮询(默认) |
upstream { server A; server B; } |
后端实例性能一致 |
|
权重(weight) |
server A weight=2; server B weight=1; |
后端实例性能不同(高性能节点权重高) |
|
IP 哈希(ip_hash) |
upstream { ip_hash; server A; server B; } |
需会话粘滞(同一客户端请求同一实例) |
|
最少连接(least_conn) |
upstream { least_conn; server A; server B; } |
后端请求处理时间差异大 |
4.4 完整配置示例(负载均衡 + 健康检查)
Nginx 原生无主动健康检查,可通过 max_fails/fail_timeout 实现被动健康检查:
nginx
upstream backend_server {
ip_hash; # 会话粘滞
server 192.168.1.10:8080 weight=2 max_fails=3 fail_timeout=30s;
server 192.168.1.11:8080 weight=1 max_fails=3 fail_timeout=30s;
# max_fails:失败次数阈值(默认1)
# fail_timeout:失败后隔离时间(默认10s)
}
server {
listen 80;
server_name localhost;
location /api/ {
proxy_pass http://backend_server/;
# 基础代理配置
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_connect_timeout 10s;
proxy_read_timeout 30s;
proxy_send_timeout 30s;
# 重试配置
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_next_upstream_tries 3; # 重试次数
}
}
4.5 负载均衡进阶配置(超时 / 重试)
|
配置项 |
作用 |
|
proxy_connect_timeout 10s |
连接后端超时时间 |
|
proxy_read_timeout 30s |
读取后端响应超时时间 |
|
proxy_next_upstream |
后端返回指定错误时,重试下一个实例(如 502/503) |
|
proxy_next_upstream_tries 3 |
最大重试次数(避免无限重试) |
五、FAQ(常见问题解答)
5.1 安装相关
Q1:Ubuntu 安装 Nginx 后启动失败,提示 80 端口被占用?
A1:执行 sudo lsof -i :80 查看占用进程(如 Apache、sshd),停止占用进程:sudo systemctl stop apache2,再启动 Nginx:sudo systemctl start nginx。
Q2:编译安装 Nginx 后,执行 nginx 命令提示 “command not found”?
A2:创建软链接:sudo ln -s
/usr/local/nginx/sbin/nginx /usr/bin/nginx,或直接执行
/usr/local/nginx/sbin/nginx。
5.2 systemctl 管理相关
Q1:执行 systemctl enable nginx 提示 “Unit nginx.service could not be found”?
A1:缘由是无 systemd 服务文件(编译安装未创建),按 2.5 节手动创建 nginx.service 文件,再执行 sudo systemctl daemon-reload。
Q2:Nginx 开机自启配置后,重启系统仍未启动?
A2:排查步骤:
- 查看启动日志:journalctl -u nginx -xe;
- 检查配置语法:nginx -t;
- 检查端口占用:sudo lsof -i :80;
- 检查权限:Nginx 托管目录需赋予 www-data 权限:sudo chown -R www-data:www-data /usr/share/nginx/html。
5.3 跨域相关
Q1:Nginx 反向代理配置后,前端仍报跨域错误?
A1:常见缘由:
- proxy_pass 末尾 / 未加,导致后端路径匹配失败;
- 前端请求地址错误(未请求 Nginx 域名,仍直接请求后端);
- 浏览器缓存了旧的预检请求,需清空缓存。
Q2:跨域携带 Cookie 时,浏览器提示 “The value of 'Access-Control-Allow-Origin' header must not be '*'”?
A2:
Access-Control-Allow-Origin 不能用 *,需指定具体前端域名(如 http://www.example.com),且前端需开启 withCredentials: true。
Q3:开发环境需要用 Nginx 解决跨域吗?
A3:不需要。前端脚手架(Vue/Vite/React)自带 devServer.proxy 代理功能,配置简单且调试高效,无需部署 Nginx。
5.4 负载均衡相关
Q1:IP 哈希策略下,新增后端实例后,会话是否会失效?
A1:会。IP 哈希基于客户端 IP 计算节点,新增 / 删除实例会改变哈希结果,可通过 weight 平滑过渡,或使用分布式会话(如 Redis)替代 IP 哈希。
Q2:Nginx 负载均衡如何实现健康检查?
A2:Nginx 原生仅支持被动健康检查(max_fails/fail_timeout),主动健康检查需安装第三方模块(如
nginx_upstream_check_module),或使用云厂商 SLB、专业网关(如 Kong)。
5.5 其他核心问题
Q1:Ubuntu 中 Nginx 有哪些配置方式?
A1:主流方式(按推荐度):
- sites-available/sites-enabled(Ubuntu 特有,多站点管理);
- conf.d 目录(通用,单站点 / 简单配置);
- 直接修改 nginx.conf(仅临时测试);
- include 引入自定义配置(复杂配置拆分);
- 命令行临时覆盖(仅测试,不持久化)。
Q2:Nginx 托管前端静态资源时,刷新页面报 404?
A2:SPA 应用(Vue/React)history 模式下,需配置 try_files $uri $uri/ /index.html;,让 Nginx 找不到静态文件时返回 index.html。
Q3:生产环境必须用 Nginx 吗?
A3:前后端分离架构中,Nginx 不是技术必需,但却是工程最优解。生产环境下,它能解决跨域、静态资源高性能托管、负载均衡、安全防护等核心问题,是企业级项目标配。

