Skip to content

Nginx、HTTPS 与 DNS

Phase 08 — Deployment · 知识点 05–08:Nginx · Reverse Proxy · HTTPS · DNS


1. 学习目标

完成本知识点后,你应该能够:

  • 安装并配置 Nginx 作为 Go 服务的 Reverse Proxy
  • 正确代理 WebSocket 连接(Upgrade / Connection 头)
  • 使用 Let's Encrypt 或云厂商证书配置 HTTPS
  • 理解 DNS A 记录 / CNAME 与域名解析流程
  • 实现 https://api.example.com + wss://api.example.com/ws 对外服务
  • 为 Three.js 前端提供安全的跨域 API 与 WSS 端点

2. 为什么需要

Go 服务监听 8080,不适合直接暴露公网:无 TLS、无静态文件能力、无负载均衡入口。Nginx 作为反向代理统一处理 443 端口、SSL 终止、WebSocket 升级,是中小型 Go 部署的标准做法。

浏览器要求 HTTPS 页面连接 WSS,DNS 将用户友好的域名解析到服务器 IP——三者共同构成数字孪生对外访问链路。


3. 核心概念

3.1 Nginx

  • 高性能 Web 服务器与反向代理
  • 监听 80/443,转发到上游 127.0.0.1:8080
  • 可托管 Vue 前端静态文件(dist/

3.2 Reverse Proxy(反向代理)

客户端 → Nginx:443 → Go:8080
         (TLS)      (HTTP)

客户端只与 Nginx 通信,不知道后端 Go 端口。

3.3 HTTPS / TLS

  • 证书证明服务器身份,流量加密
  • Let's Encrypt 免费自动续期(certbot)
  • Go 服务可在 Nginx 后继续使用 HTTP(内网可信)

3.4 DNS

记录类型用途
A域名 → IPv4(api.example.com203.0.113.10
CNAME域名 → 另一域名(wwwexample.com
TTL缓存时间,变更后等待传播

4. 基础语法

4.1 Nginx 站点配置

/etc/nginx/sites-available/twin-api

nginx
upstream twin_backend {
    server 127.0.0.1:8080;
    keepalive 32;
}

server {
    listen 80;
    server_name api.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name api.example.com;

    ssl_certificate     /etc/letsencrypt/live/api.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;

    # API
    location / {
        proxy_pass http://twin_backend;
        proxy_http_version 1.1;
        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;
    }

    # WebSocket
    location /ws {
        proxy_pass http://twin_backend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
    }
}
bash
sudo ln -s /etc/nginx/sites-available/twin-api /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

4.2 Let's Encrypt(certbot)

bash
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d api.example.com
sudo certbot renew --dry-run

4.3 前端静态站点(可选)

nginx
server {
    listen 443 ssl http2;
    server_name twin.example.com;
    root /var/www/twin/dist;
    index index.html;
    location / {
        try_files $uri $uri/ /index.html;
    }
}

Three.js SPA 路由需 try_files 回退到 index.html

4.4 前端连接 WSS

javascript
const wsUrl = location.protocol === 'https:'
  ? 'wss://api.example.com/ws'
  : 'ws://localhost:8080/ws';
const ws = new WebSocket(wsUrl);

5. 代码解析

proxy_http_version 1.1:WebSocket 依赖 HTTP/1.1 Upgrade。

Upgrade / Connection:必须转发,否则 WS 握手失败,Three.js 无法收 AGV 数据。

proxy_read_timeout 3600s:长连接默认 60s 可能断开,调大适配数字孪生长会话。

X-Forwarded-Proto:Go 服务可据此生成正确的外部 URL(若需要)。

HTTP → HTTPS 301:强制加密,避免明文泄露 JWT。


6. JavaScript / TypeScript 对比

概念前端基础设施
API 基址VITE_API_URLNginx → Go
WSSnew WebSocket(wss://...)Nginx WS 代理
混合内容HTTPS 页不能连 ws://必须 wss://
静态资源Vite buildNginx root

Vue 环境变量在构建时注入;确保生产 VITE_WS_URL 指向 wss。


7. 常见错误

错误 1:WebSocket 502 / 立即断开

缺少 Upgrade / Connection 头,或 proxy_pass 路径不匹配。

错误 2:Mixed Content

HTTPS 页面连接 ws:// 被浏览器拦截 → 改 wss://

错误 3:DNS 未生效就申请证书

certbot 验证失败 → 先确认 dig api.example.com 指向正确 IP。

错误 4:CORS 与 Nginx 混淆

CORS 是 Go 中间件处理;Nginx 不替代 CORS 逻辑。

错误 5:证书过期

配置 certbot 定时续期 renew cron/systemd timer。


8. 实际应用

数字孪生完整访问链路

用户浏览器
  → DNS: twin.example.com (前端)
  → DNS: api.example.com (API/WSS)
  → Nginx TLS
  → Go :8080
  → WebSocket 推送 AGV → Three.js 更新场景

验收清单

  • [ ] https://api.example.com/health 返回 200
  • [ ] wss://api.example.com/ws 连接成功
  • [ ] Three.js 页面无 Mixed Content 警告
  • [ ] HTTP 自动跳转 HTTPS

9. 深入理解

9.1 SSL 终止 vs 透传

本路线采用 Nginx 终止 TLS,Go 处理明文——简单且性能足够。端到端 TLS 到 Go 更复杂,非本阶段重点。

9.2 多实例负载均衡

nginx
upstream twin_backend {
    server 127.0.0.1:8081;
    server 127.0.0.1:8082;
}

WebSocket 需 sticky session 或 Redis Pub/Sub 跨实例(Phase 06 扩展)。

9.3 HTTP/2 与 WebSocket

浏览器 WS 仍基于 HTTP/1.1 Upgrade;Nginx 对 WS location 走 HTTP/1.1 到上游即可。


10. 练习

详细练习见 exercises/phase-08-deployment/02-nginx-https-dns.md

Level 1 — 基础

练习 1.1:Nginx 反代 http://127.0.0.1:8080,本机 curl 验证。

练习 1.2:添加 /ws WebSocket 代理配置,浏览器 wss 测试。

Level 2 — 应用

练习 2.1:配置 DNS A 记录(或 hosts 模拟),certbot 申请 HTTPS。

练习 2.2:HTTP 301 跳转 HTTPS。

Level 3 — 综合

练习 3.1:同时托管 Vue dist 静态站 + API 子域名分离。

练习 3.2:调整 proxy 超时,模拟长连接 30 分钟不断。

Level 4 — 项目实践

练习 4.1:Project 03 公网 HTTPS + WSS 联调 Three.js 演示页。


11. 学习检查

  1. 反向代理与正向代理区别?
  2. WebSocket 代理必须配置哪些 header?
  3. 为什么 HTTPS 页面必须用 WSS?
  4. A 记录与 CNAME 如何选择?
  5. certbot 续期如何验证?

12. 下一步

已完成下一知识点关系
Nginx · HTTPS · DNSCI/CD · Production Deployment手动部署就绪 → 自动化流水线

下一步建立 GitHub Actions 等 CI/CD,实现测试、构建、部署自动化,并编写生产运行手册。


学习导航

上一篇:Linux 运维基础 · 对应练习 · 下一篇:CI/CD 与生产部署