刚工作的时候,"nginx"对我来说就是一个黑盒——运维配好我就用,出了问题只会重启。直到有一次线上 https 证书过期,整个排查过程我 插不上手,才下决心自己学了一遍。
nginx 是干什么的
简单说就三件事:
- 静态文件服务:直接返回 html/css/js/图片
- 反向代理:把请求转发给后端服务(tomcat、node、go 等)
- 负载均衡:多个后端实例,nginx 帮你分发请求
大部分项目里,nginx 同时干这三件事。
核心配置文件结构
# nginx.conf 主配置
worker_processes auto; # 工作进程数,auto = cpu 核数
events {
worker_connections 1024; # 每个进程最大连接数
}
http {
include mime.types;
sendfile on; # 零拷贝传输,静态文件必开
keepalive_timeout 65;
# 虚拟主机 1
server {
listen 80;
server_name example.com;
location / {
root /var/www/html;
index index.html;
}
}
# 虚拟主机 2(反向代理)
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://127.0.0.1:8080;
}
}
}http → server → location 三层嵌套,每一层都可以有独立的配置。
反向代理配置
最基本的一条:
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://127.0.0.1:8080;
# 传递真实客户端信息给后端
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_set_header 这四行基本是固定写法,不加的话后端拿到的 ip 全是 nginx 的 127.0.0.1。
按路径转发到不同后端
server {
listen 80;
server_name example.com;
# api 请求 → java 后端
location /api/ {
proxy_pass http://127.0.0.1:8080;
}
# websocket → node 服务
location /ws/ {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header upgrade $http_upgrade;
proxy_set_header connection "upgrade";
}
# 静态文件 → 直接返回
location / {
root /var/www/frontend/dist;
try_files $uri $uri/ /index.html; # spa 路由兜底
}
}try_files 那行是 spa 标配——前端用 vue router / react router 的 history 模式时,所有路径都要返回 index.html,否则刷新就 404。
https 配置
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/nginx/ssl/example.com.pem;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
ssl_protocols tlsv1.2 tlsv1.3;
ssl_ciphers high:!anull:!md5;
location / {
proxy_pass http://127.0.0.1:8080;
}
}
# http 自动跳转 https
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}证书用 let's encrypt 免费申请,certbot 一行命令搞定续期。
负载均衡
upstream backend {
# 默认轮询
server 192.168.1.10:8080 weight=3; # 权重高的分更多请求
server 192.168.1.11:8080 weight=1;
server 192.168.1.12:8080 backup; # 备用,前两台挂了才用
# 也可以用 ip_hash(同一 ip 始终打到同一台,解决 session 问题)
# ip_hash;
# 或者 least_conn(请求最少的优先)
# least_conn;
}
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://backend;
}
}| 策略 | 说明 | 适用场景 |
|---|---|---|
| 轮询 (默认) | 按顺序依次分发 | 后端实例性能一致 |
| weight | 按权重比例分发 | 后端性能不一致 |
| ip_hash | 同一 ip 固定到同一台 | 有 session 依赖 |
| least_conn | 优先分给连接数最少的 | 请求处理时间差异大 |
常用运维命令
# 测试配置文件语法 nginx -t # 重新加载配置(不中断服务) nginx -s reload # 查看 nginx 进程 ps aux | grep nginx # 查看当前连接数 netstat -nlp | grep nginx
改完配置一定要先 nginx -t 测一下语法,再 nginx -s reload。直接 restart 会短暂中断连接。
踩坑:proxy_pass 末尾的斜杠
# 有斜杠:/api/users → http://backend/users(去掉了 /api)
location /api/ {
proxy_pass http://backend/;
}
# 没斜杠:/api/users → http://backend/api/users(保留 /api)
location /api/ {
proxy_pass http://backend;
}这个坑我见过不下三次,前后端联调的时候路径对不上,排查半天发现是斜杠的问题。记住:proxy_pass 后面有路径(哪怕只是一个 /),就会替换掉 location 的匹配部分。
总结
nginx 日常用到的就是:反向代理(proxy_pass)、静态文件(root + try_files)、https(ssl_certificate)、负载均衡(upstream)。配完记得 nginx -t 测语法,proxy_pass 注意斜杠。
以上就是nginx反向代理配置的完整指南的详细内容,更多关于nginx反向代理配置的资料请关注代码网其它相关文章!
发表评论