前面苏米分享过不少部署和提效的工具,今天聊一个我做独立开发这几年最常用、也最省钱的“老伙计”——Nginx。
很多同学把 Nginx 当成“静态资源服务器”或者“反向代理”,但在我的出海网站、工具型产品和多服务架构里,它更像是瑞士军刀:流量入口、负载均衡、TLS 终端、缓存加速、限流防刷,全都能干。
这篇我不只讲“怎么配”,还会结合我在大厂10年+独立开发的项目经验,把常见坑、生产优化、上线套路一次性讲透。
看完,你能从零装好 Nginx,理解 server/location 的匹配逻辑,敢把线上站点的 HTTPS、反向代理、静态加速、限流都跑起来。
1. 认识 Nginx
Nginx 是一个免费开源、占用资源极低、性能又很强的 Web 和反向代理服务器。打个比方,它像一个“菜鸟驿站”:
- 你去拿快递(浏览器访问网址发起请求)
- 驿站员工按取件码到对应货架拿件(Nginx 根据请求路径与规则,返回对应服务器资源)
但 Nginx 不止会“分发快递”,它还能:
- 做静态资源服务(HTML/CSS/JS/图片极速分发)
- 反向代理和负载均衡(把请求转发到后端 Node/Go/Java 应用,甚至多节点分流)
- 作为 TLS 终端(统一处理 HTTPS,后端走内网明文,更简单更安全)
- 缓存与压缩(降低后端压力,提升首屏速度)
- 限流、防刷、黑名单(出海项目非常有用)
作为独立开发者,我之所以常年选 Nginx,是因为它稳定、配置清晰、学习曲线平滑,一台小实例就能撑起多个服务和域名。
2. 在 Linux 安装 Nginx
以下命令以 CentOS/RedHat 系为例(Ubuntu/Debian 用 apt 命令类似):
# 安装 Nginx
sudo yum install nginx
# 启动 Nginx
sudo systemctl start nginx
# 设置开机自启
sudo systemctl enable nginx
# 查看运行状态
sudo systemctl status nginx
常用默认路径:
- 静态资源根目录:
/usr/share/nginx/html - 主配置目录:
/etc/nginx - 主配置文件:
/etc/nginx/nginx.conf - 子配置目录:
/etc/nginx/conf.d/
一个典型的 nginx.conf 长这样(核心注释我补充在旁边):
user nginx;
worker_processes auto; # 自动根据 CPU 核心数
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
events {
worker_connections 1024; # 单进程最大并发连接数
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on; # 优化 TCP 包
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
gzip on; # 开启 gzip 压缩(生产建议按类型细化)
include /etc/nginx/mime.types;
default_type application/octet-stream;
include /etc/nginx/conf.d/*.conf; # 推荐把站点配置放在 conf.d 里
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
location / {
index index.html index.htm; # 默认文档
}
error_page 404 /404.html;
location = /40x.html { }
error_page 500 502 503 504 /50x.html;
location = /50x.html { }
}
}
3. Server 配置详解(虚拟主机)
3.1 最基本的 server
一个 server 表示一个虚拟主机,用来监听端口、匹配域名并处理请求:
listen:监听端口server_name:域名(请求的 Host)root:默认文件目录location:路径映射与处理规则
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
location / {
index index.html index.htm;
}
}
当你访问该服务器的 80 端口时,默认会返回 /usr/share/nginx/html 下的 index.html。如果你把公司官网的 index.html 放进去,访问这台服务器的 IP 或域名,就能看到官网页面。
想换一个目录?有两种方式:
# 方案1:修改 server 级别的 root
server {
listen 80;
server_name localhost;
root /usr/local/zhifou;
location / {
index index.html index.htm;
}
}
# 方案2:在 location 中指定(更灵活,但不宜到处乱用)
server {
listen 80;
server_name localhost;
root /usr/local/zhifou;
location / {
root /usr/local/assets;
index index.html index.htm;
}
}
注意:
- 修改配置后先校验再重载:
sudo nginx -t && sudo systemctl reload nginx - location 与 server 的
root都生效,优先取命中的 location 块内的配置。只是root和alias的拼接规则不同(后文详解)。 - 实际项目中不建议到处在 location 里改 root,容易混乱;能用
alias就用alias。
3.2 多个 server(多站点/多端口)
同一台机器可以同时跑多个端口或多个域名:
server {
listen 80;
server_name localhost;
location / {
root /usr/local/assets;
index index.html index.htm;
}
}
server {
listen 8080;
server_name localhost;
location / {
root /usr/local/assets/blog;
index index.html index.htm;
}
}
3.3 server_name 详解
server_name 是域名匹配规则,生产里常见几种写法:
# 精确匹配多个域名
server_name example.com www.example.com;
# 通配符(子域名)
server_name *.example.com;
# 正则匹配(更灵活,但别滥用)
server_name ~^api\d+\.example\.com$;
# 默认站点(兜底),同端口下未命中的请求会走它
listen 80 default_server;
server_name _;
本地调试可用 /etc/hosts 或用 curl 指定 Host:
curl -H "Host: example.com" http://127.0.0.1/
4. Location 路径映射与优先级
location 是 Nginx 最强的能力之一。先记住这条优先级规则(很关键):
- 1)精确匹配:
location = /path - 2)前缀匹配:记录“最长前缀”的普通
location /xxx - 3)遇到
^~前缀:命中后不再去匹配正则 - 4)正则匹配:
location ~ /regex或~*(大小写不敏感),按出现顺序匹配 - 最终:若正则没有命中,则使用“最长前缀”的那个普通 location
4.1 精确匹配
location = /blog {
# 仅请求 URI 完全等于 /blog 才命中
# 一般用于少数特殊页面
root /usr/local/assets; # 在精确匹配中也生效
index index.html;
}
很多同学误以为“精确匹配里 root 不生效”,其实是被路径拼接规则绕晕了:root 始终是“root + URI”拼接;如果 URI 是 /blog 而你的静态文件是在 /usr/local/assets/blog/index.html,就能命中。排错时多看 /var/log/nginx/error.log。
4.2 前缀匹配 + 静态加速(用 root)
location ^~ /assets/ {
root /usr/local; # 访问 /assets/img/logo.png => /usr/local/assets/img/logo.png
expires 7d; # 缓存 7 天
add_header Cache-Control "public, max-age=604800";
autoindex off;
}
4.3 前缀匹配(用 alias 映射目录)
alias 的语义是“替换前缀”,和 root 的“拼接”不同。用于把一个 URL 前缀直接映射到某个目录:
location ^~ /static/ {
alias /usr/local/assets/; # 注意以 / 结尾
expires 7d;
add_header Cache-Control "public, max-age=604800";
autoindex off;
}
4.4 正则匹配(黑名单、类型控制)
# 禁止访问隐藏文件(以 "." 开头)
location ~ /\. {
deny all;
log_not_found off;
}
# .html 不缓存(示例)
location ~* \.html$ {
root /var/www/html;
expires -1;
add_header Cache-Control "no-store, no-cache";
}
# 视频文件缓存 30 天,支持断点续传
location ~* \.(mp4|m3u8|ts)$ {
root /data/videos;
expires 30d;
add_header Cache-Control "public";
add_header Accept-Ranges bytes;
}
4.5 普通前缀匹配(最长路径优先)
location /static {
alias /usr/local/assets;
expires 30d;
}
当多个前缀都能匹配时,会选择路径最长的那个。
5. 反向代理与负载均衡(独立开发的“后端入口”)
大多数工具站或 API 都是前后端分离,Nginx 作为统一入口最舒服。一个最常用的 upstream 配法如下:
upstream app_backend {
server 127.0.0.1:3000 max_fails=3 fail_timeout=30s;
server 127.0.0.1:3001 max_fails=3 fail_timeout=30s;
keepalive 32; # 复用连接,减少后端压力
}
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://app_backend;
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;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; # WebSocket
proxy_set_header Connection "upgrade"; # WebSocket
proxy_read_timeout 60s;
}
}
经验提示:
- 务必传递真实 IP(
X-Real-IP、X-Forwarded-For),否则后端日志全是 127.0.0.1。 - WebSocket 场景要加 Upgrade/Connection。
- 多节点负载均衡默认是轮询,复杂场景可选
least_conn、ip_hash等策略。
6. 一键上 HTTPS(Let’s Encrypt)
生产强烈建议都上 HTTPS,Nginx 当 TLS 终端最省心。
# 以 Debian/Ubuntu 为例
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com
# 自动续期会装好;检查续期定时任务
sudo systemctl status certbot.timer
手动写也可:
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri; # 全站跳转到 HTTPS
}
server {
listen 443 ssl http2;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# 建议开启 HSTS(按需)
add_header Strict-Transport-Security "max-age=31536000" always;
# 你的站点 location...
}
7. 生产优化与避坑清单(独立开发实战版)
- 配置变更流程:
nginx -t校验配置 →systemctl reload nginx热重载,零停机。 - 日志与排错:
tail -f /var/log/nginx/error.log、access.log;精简log_format,避免写入过重。 - 上传大小:按业务设置
client_max_body_size 50M;,否则用户上传直接 413。 - 压缩与缓存:静态资源
expires+Cache-Control;按类型开启gzip(如text/css、application/javascript)。 - 限流防刷:对登录、短信、API 做限流非常重要(出海项目必备)。
# 以 IP 为维度,每秒 10 次,最多突发 20 次
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
server {
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
proxy_pass http://app_backend;
}
}
- 目录结构:CentOS 推荐用
/etc/nginx/conf.d/xxx.conf分站点;Debian/Ubuntu 可用sites-available/sites-enabled约定。 - alias vs root:映射子目录优先用
alias,记得末尾加/;root是“root + URI”拼接,别混用导致路径错位。 - 长连接与性能:
keepalive_timeout、upstream keepalive合理设置;高并发场景用worker_processes auto+ 合理worker_connections。
8. 常用调试手段(省时间的都是好手段)
- 看优先级:临时在命中的 location 里加一个特殊 header,
add_header X-Debug "loc-A";,curl 看响应确认是否命中。 - 模拟 Host:
curl -H "Host: test.example.com" http://127.0.0.1/ - 只测配置:
nginx -t,别一改就重启。 - 观察缓存:配了
expires后,用浏览器 DevTools → Network 看 Response Headers 是否生效。
9. 小结:把 Nginx 当“流量入口”,你的独立产品会更稳更省
从大厂到独立开发,能稳定支撑多个小产品、快速上线的能力很关键。Nginx 是我几乎所有线上项目的“第一道门”:域名/端口路由、静态加速、反向代理、HTTPS、限流、日志观测… 一套搞定,性价比极高。今天的教程从基本 server/location 理念,到反向代理、TLS、生产优化,我把实战里最常用的心法都放进来了。你可以先从一个静态站点开始,再把后端挂到 upstream,最后启用 HTTPS 与限流,完整跑起来就是一个可上线的最小闭环。
如果这篇对你有帮助,帮苏米点个赞、转发给需要的朋友,或者留言你的 Nginx 疑问。你们的支持是我持续输出的最大动力!