云服务器运维与项目部署
13.10 端口映射实战
Tip
你的 Node.js 应用跑在localhost:3000。但用户访问的是 http://domain.com (默认端口 80)。你需要一个中间人把 80 的流量转给 3000。这个中间人就是 Nginx (Reverse Proxy)。
1. 为什么要学这个?
你在服务器上启动了 npm start,显示 Listening on 3000。
你在浏览器输入 http://1.2.3.4,打不开。
输入 http://1.2.3.4:3000,打开了。
太丑了。 没人会在网址后面输端口号。你需要把它藏起来。
2. 核心概念:Reverse Proxy (反向代理)
正向代理 vs 反向代理
- 正向代理 (VPN):代表用户。你通过梯子访问谷歌,谷歌以为是梯子在访问它。(隐藏了用户)
- 反向代理 (Nginx):代表服务器。用户访问 Nginx,Nginx 找后台拿数据。(隐藏了服务器)
作用:
- 去端口号:3000 -> 80。
- 负载均衡:把请求分给 3 个 Node 实例。
- SSL 卸载:统一在 Nginx 处解密 HTTPS,后端只处理 HTTP。
3. 解决方案 (HOW)
3.1 1Panel 方式 (小白推荐)
- 创建网站 -> 反向代理。
- 代理地址:
http://127.0.0.1:3000。 - 确认。
- 搞定。1Panel 会自动生成 Nginx 配置。
3.2 手写 Nginx 配置 (硬核)
编辑 /etc/nginx/sites-available/default:
server {
listen 80;
server_name mydomain.com;
location / {
# 核心:把请求转发给本地 3000 端口
proxy_pass http://127.0.0.1:3000;
# 必带的头信息 (否则后端不知道用户真实 IP)
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
3.3 流量转发图
graph TD
User["用户浏览器"] -->|"Step 1: HTTP (80)"| Nginx["Nginx (门卫)"]
subgraph Server ["云服务器内部"]
Nginx -->|"Step 2: 转发 (3000)"| App1["Node.js 应用"]
Nginx -->|"Step 3: 转发 (8080)"| App2["Java 后端"]
end
App1 --"Step 4: 响应"--> Nginx
Nginx --"Step 5: 响应"--> User
style Nginx fill:#e1bee7,stroke:#8e24aa
style App1 fill:#c8e6c9,stroke:#2e7d32
4. 避坑指南
| ❌ 不要这样做 | ✅ 应该这样做 | 为什么 |
|---|---|---|
| 丢 Header | 透传 Header | 忘了传 X-Real-IP。后端日志里全是 127.0.0.1,无法统计用户来源,也无法做 IP 限流。 |
| WebSocket | 配置 Upgrade | Socket.io 连接失败。因为 Nginx 默认不支持 WebSocket 长连接,需要配置 Upgrade 头。 |
| 大文件超时 | 调大 Timeout | 上传大文件报错 504。Nginx 默认超时 60s,上传视频必须调大 client_max_body_size 和 proxy_read_timeout。 |
5. 真实案例
Story
2021年,死循环的重定向
某开发者配置了 Nginx:HTTP -> HTTPS 强制跳转。 但他在 Cloudflare (CDN) 上也开启了 "Flexible SSL" (CDN 到源站只走 HTTP)。 结果: 用户 -> HTTPS -> Cloudflare -> HTTP -> Nginx (Trigger 301) -> HTTPS -> Cloudflare -> HTTP -> Nginx ... 浏览器报错 "Too many redirects"。
Vibe 心法:Nginx 是互联网的“交通警察”。在多层代理的链路中,清晰的转发逻辑是排错的关键。别忘了在透传时带上用户的原始 IP(Header),否则你的后端将永远迷失在 127.0.0.1 的迷雾里。
6. 本章小结
- Nginx:是互联网的交通警察。
- Proxy Pass:是最常用的 Nginx 指令。
- Headers:转发时别忘了带上用户的“身份证” (IP/Host)。