【Nginx】Nginx 反向代理设置 ( 内网访问需求 | Nginx 服务器常用命令 | Nginx 反向代理部署方案 )

文章目录

  • 一、内网访问需求
  • [二、Nginx 反向代理](#二、Nginx 反向代理)
  • [三、Nginx 服务器常用命令](#三、Nginx 服务器常用命令)
    • [1、Nginx 常用命令](#1、Nginx 常用命令)
    • [2、Nginx 启动脚本](#2、Nginx 启动脚本)
    • [3、Nginx 终止脚本](#3、Nginx 终止脚本)
  • [四、Nginx 反向代理部署方案](#四、Nginx 反向代理部署方案)
    • [1、Nginx 下载](#1、Nginx 下载)
    • [2、Nginx 配置](#2、Nginx 配置)
    • [3、Nginx 配置注释详解 ( 仅做参考 )](#3、Nginx 配置注释详解 ( 仅做参考 ))

一、内网访问需求


业务网络环境 :

  • 客户端 : 手机移动端 , 仅能接入公网 , 无法直接访问企业内网 ;
  • 业务服务端 : 内网业务服务器 , 仅内网可达 , 无公网暴露地址 , 不允许直接对公网开放端口 ;
  • 中转节点 : 内网前置机 , 属于双通节点 , 同时具备访问公网、访问内网服务器的网络权限 , 作为唯一流量中转枢纽 ;

整体核心目标 : 依托 " 内网双通前置机 " 搭建统一流量转发网关 , 实现公网手机端跨网络访问内网服务器 , 完整兼容三类通信协议 : HTTP、WebSocket、原生 TCP , 所有客户端流量均经过前置机中转 , 内网服务器不直接暴露公网 ;

前置机部署一套转发服务程序 , 该程序需要同时承担三类服务角色 :

  • HTTP 服务端 : 接收手机端 HTTP 请求 ;
  • WebSocket 服务端 : 建立并维持手机端 WebSocket 长连接 ;
  • TCP 服务端 : 监听端口接收手机端原生 TCP 长连接 ;

程序需为每一条来自手机端的独立连接 / 请求 , 在内存中维护独立连接实例 , 隔离不同手机客户端流量 , 互不干扰 ;

二、Nginx 反向代理


在 内网双通前置机 ( 能访问公网、也能访问内网业务服务器 ) 上 部署 Nginx 反向代理 ;

基于 Nginx 反向代理 , 实现公网手机访问内网服务器 的 HTTP/WS/TCP 全协议中转方案 ;

  • 网络隔离 : 手机客户端 仅能访问公网 , 业务服务器在内网部署 , 不可直连公网 ;
  • Nginx 版本要求 : 必须带 stream 模块 ( TCP 四层转发 ) + http 模块 ( HTTP/WS 七层代理 ) , 主流 yum/apt 安装的 nginx 默认支持 , 编译安装需加--with-stream ;
  • 架构逻辑 : 手机端全部流量打到前置机 Nginx , Nginx 分别做七层 HTTP/WS 反向代理、四层 TCP 流转发 , 统一中转至内网服务器 ;

三、Nginx 服务器常用命令


1、Nginx 常用命令

进入到 nginx 根目录 nginx-1.30.3 , 打开命令行终端 , 执行如下命令 ;

shell 复制代码
# 1. 校验配置
nginx.exe -t

# 2. 热重载配置 ( 修改conf后 , 不中断连接 ) 
nginx.exe -s reload

# 3. 优雅关闭 ( 等待连接处理完 ) 
nginx.exe -s quit

# 4. 强制关闭
nginx.exe -s stop

# 5. 后台启动
start nginx.exe

常用命令 :

shell 复制代码
# 调试启动 , 开发测试使用
nginx.exe

# 后台启动 , 生产环境使用 
start nginx.exe

# 查询所有nginx进程
tasklist | findstr nginx

# 强制结束所有nginx
taskkill /f /im nginx.exe

2、Nginx 启动脚本

StartNginx.bat 脚本内容 :

shell 复制代码
:: 关闭脚本自身命令行指令回显 , 只输出手动echo内容
@echo off
:: 设置控制台编码为UTF-8 , 屏蔽编码切换的输出信息
chcp 65001 >nul
:: 1. 校验Nginx配置文件
echo ====================== CHECK NGINX CONFIGURATION ======================
nginx.exe -t
:: 判断上一条命令执行返回码 , 非0代表配置检测失败
if %errorlevel% neq 0 (
    echo [ERROR] nginx.conf syntax error, startup aborted!
    echo Check logs\error.log for detailed information
    pause
    exit /b 1
)

:: 2. 强制结束残留Nginx进程 , 防止端口占用
echo ====================== CLEAN RESIDUAL NGINX PROCESSES =================
:: 强制结束所有nginx.exe进程 , 屏蔽命令执行输出与错误输出
taskkill /f /im nginx.exe >nul 2>&1
:: 等待1秒 , 不响应按键 , 给进程关闭留出缓冲时间
timeout /t 1 /nobreak >nul

:: 3. 最小化后台静默启动Nginx , 不保留控制台窗口
echo ====================== START NGINX BACKGROUND SERVICE =================
:: 最小化新开窗口运行nginx.exe , 后台常驻
start /min nginx.exe

echo ====================== NGINX RUNNING IN BACKGROUND ====================
echo ====================== VERIFY NGINX RUNNING PROCESSES =================
:: 列出系统进程并过滤nginx相关进程 , 确认是否成功启动
tasklist | findstr nginx
:: 等待2秒 , 不响应按键 , 方便用户查看进程输出结果
timeout /t 2 /nobreak >nul
:: 脚本执行完毕暂停 , 防止双击运行后窗口自动一闪关闭
pause

编辑完成后 , 将脚本放在根目录即可 ;

执行脚本 :

shell 复制代码
====================== CHECK NGINX CONFIGURATION ======================
nginx: the configuration file D:\001_Develop\026_Nginx_Learn\nginx-1.30.3/conf/nginx.conf syntax is ok
nginx: configuration file D:\001_Develop\026_Nginx_Learn\nginx-1.30.3/conf/nginx.conf test is successful
====================== CLEAN RESIDUAL NGINX PROCESSES =================
====================== START NGINX BACKGROUND SERVICE =================
====================== NGINX RUNNING IN BACKGROUND ====================
====================== VERIFY NGINX RUNNING PROCESSES =================
nginx.exe                    25672 Console                    1      8,728 K
nginx.exe                    14436 Console                    1      4,660 K
Press any key to continue . . .

3、Nginx 终止脚本

StopNginx.bat 脚本内容 :

shell 复制代码
:: 关闭脚本自身命令行指令回显 , 只输出手动echo内容
@echo off
:: 设置控制台编码为UTF-8 , 屏蔽编码切换的输出信息
chcp 65001 >nul
:: 发送优雅退出信号 , 关闭正在运行的Nginx进程
nginx.exe -s quit
:: 输出停止完成提示 , 分隔线长度统一对齐
echo ====================== NGINX STOPPED GRACEFULLY ======================
pause

编辑完成后 , 将脚本放在根目录即可 ;

执行脚本 :

shell 复制代码
====================== NGINX STOPPED GRACEFULLY ======================
Press any key to continue . . .

四、Nginx 反向代理部署方案


1、Nginx 下载

Nginx 下载地址 : https://nginx.org/en/download.html , 下载 最新的 稳定版本 ,

上面五个文件 CHANGES-1.30 nginx-1.30.3 pgp nginx/Windows-1.30.3 pgp 分别是 :

  • CHANGES-1.30 : 1.30 稳定分支全变更日志 , 记录从 1.30.0 ~ 1.30.3 所有新增功能、Bug 修复、安全漏洞修复、配置行为改动 ; 线上升级前必看 , 用来判断是否有破坏性变更、CVE 安全补丁 ;
  • nginx-1.30.3 : Linux/Unix 源码包 ( 稳定版 1.30.3 ) , 用于 CentOS、Ubuntu、Debian 等 Linux 服务器编译安装 , 生产环境主流包 ;
  • 第一个 pgp : Linux 源码包的 PGP 数字签名文件用官方 GPG 公钥校验压缩包完整性、防篡改、确认是官方原版 , 防止下载被劫持 ;
  • nginx/Windows-1.30.3 : Windows 二进制免编译包 ( 稳定版 1.30.3 ) 开箱即用 , Windows Server / 个人 Windows 系统直接解压运行 , 无需编译 ;
  • 第二个 pgp : Windows 压缩包对应的 PGP 签名文件校验 Windows 版安装包未被篡改 ;

nginx/Windows-1.30.3 的 直接下载地址 : https://nginx.org/download/nginx-1.30.3.zip

2、Nginx 配置

下载后解压 nginx-1.30.3.zip 文件 , 得到 nginx-1.30.3 目录 ,

编辑 nginx-1.30.3\conf\nginx.conf 配置文件 ;

json 复制代码
worker_processes auto;
error_log logs/error.log warn;
pid logs/nginx.pid;

events {
    worker_connections 20480;
}

stream {
    upstream tcp_backend {
        server 39.156.70.239:8082;
    }

    server {
        listen 8082;
        proxy_pass tcp_backend;
        proxy_connect_timeout 10s;
        proxy_timeout 3600s;
        tcp_nodelay on;
        proxy_buffer_size 4k;
    }
}

http {
    include mime.types;
    default_type application/octet-stream;

    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 logs/http_ws_access.log main;

    sendfile on;
    keepalive_timeout 60;
    client_max_body_size 100M;

    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_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    upstream http_backend {
        server 39.156.70.239:8080;
    }

    server {
        listen 8080;
        server_name _;

        location / {
            proxy_pass http://http_backend;
            proxy_read_timeout 30s;
            proxy_send_timeout 30s;
        }
    }

    upstream ws_backend {
        server 39.156.70.239:8081;
    }

    server {
        listen 8081;
        server_name _;

        location / {
            proxy_pass http://ws_backend;
            proxy_read_timeout 3600s;
            proxy_send_timeout 3600s;
        }
    }
}

3、Nginx 配置注释详解 ( 仅做参考 )

配置文件 原理 和 用途 注释版本 :

json 复制代码
# =============================================================================
# Nginx 主配置文件 ------ 详细中文注释版
# 适用版本: nginx/1.30.3
# 配置目标: 同时承载 TCP 四层代理、HTTP 七层代理、WebSocket 长连接代理
# 核心原理: Nginx 采用 master-worker 多进程模型 , master 负责管理 , worker 处理连接
# =============================================================================

# ==========================================
# 全局进程配置块 (main 上下文)
# 作用域: 影响整个 Nginx 服务器的运行行为
# 执行逻辑: 此块在 Nginx 启动时最先被解析 , 决定系统级资源分配
# ==========================================

# 【配置项】worker_processes auto;
# 【原理】Nginx 采用多进程模型 , master 进程负责管理 , worker 进程负责处理客户端请求 ; 
#         每个 worker 进程是单线程的 , 通过 epoll/kqueue 等 IO 多路复用机制实现高并发 ; 
#         "auto" 表示自动检测服务器 CPU 核心数 , 并为每个核心创建一个 worker 进程 ; 
#         例如 8 核 CPU 会创建 8 个 worker 进程 , 实现真正的并行处理 ; 
# 【用途】充分利用多核 CPU 性能 , 避免单个 worker 成为瓶颈 , 同时避免进程过多导致上下文切换开销 ; 
# 【建议】通常设为 auto 或 CPU 核心数 , IO 密集型可设为 2 倍核心数 ; 
worker_processes auto;

# 【配置项】error_log logs/error.log warn;
# 【原理】Nginx 将所有运行期间的错误、警告、调试信息写入指定日志文件 ; 
#         日志级别从低到高依次为: debug → info → notice → warn → error → crit → alert → emerg ; 
#         只有高于等于设定级别的日志才会被记录 , 低级别日志会被过滤 ; 
#         日志文件采用追加写入模式 , 不会覆盖历史日志 ; 
# 【用途】warn 级别记录警告和更严重的错误 , 适合生产环境排查问题 , 避免 debug 级别产生过大日志 ; 
#         日志路径 "logs/error.log" 是相对于 Nginx 安装目录的相对路径 ; 
error_log logs/error.log warn;

# 【配置项】pid logs/nginx.pid;
# 【原理】Nginx 启动时 , master 主进程的进程 ID (PID) 会被写入此文件 ; 
#         系统通过 PID 文件向 Nginx 发送信号 (如 HUP 重载、TERM 优雅退出、USR1 日志切割) ; 
#         例如: `kill -HUP $(cat logs/nginx.pid)` 实现配置热重载 , 无需中断服务 ; 
# 【用途】为系统管理脚本、服务管理器 (systemd/supervisor) 提供进程标识 , 是平滑升级和信号控制的基石 ; 
pid logs/nginx.pid;

# ==========================================
# 事件模块配置块 (events 上下文)
# 【核心机制】Nginx 使用事件驱动架构处理网络连接 ; 
#            Linux 下默认使用 epoll , FreeBSD/macOS 使用 kqueue , Windows 使用 select/iocp ; 
#            epoll 基于内核事件通知 , 无需轮询 , 单线程可支撑数万并发连接 ; 
# ==========================================
events {
    # 【配置项】worker_connections 20480;
    # 【原理】每个 worker 进程可以同时维持的最大连接数 ; 
    #         一个连接可能同时涉及读和写两个事件 , 因此实际并发连接数可能减半 ; 
    #         系统层面还受限于 `ulimit -n` (文件描述符上限) , 需同步调整 ; 
    #         总并发连接上限 ≈ worker_processes × worker_connections / (每个连接的句柄数) ; 
    # 【用途】20480 的设定适配大规模长连接场景 ( 如物联网设备、手机 APP 保活连接 )  ; 
    #         例如 8 个 worker 进程 , 理论最大并发可达 8 × 20480 = 163840 连接 ; 
    worker_connections 20480;
}

# ==========================================
# Stream 四层 TCP 代理模块
# 【核心原理】在 OSI 网络模型的传输层 ( 第4层 ) 工作 , 直接转发 TCP/UDP 数据包 ; 
#            不解析应用层协议 ( 如 HTTP )  , 仅根据 IP 和端口进行转发 ; 
#            性能极高 , 延迟极低 , 适用于数据库、MQTT、自定义二进制协议等 TCP 流量 ; 
#            Nginx 从 1.9.0 版本开始引入 stream 模块 , 1.30.3 已完全支持 ; 
# ==========================================
stream {
    # 【以下为注释掉的配置 , 说明不启用原因】
    # 【原理】stream 模块在早期版本中不支持 HTTP 模块的某些日志变量 ; 
    #         $bytes_in 和 $bytes_out 分别表示接收和发送的字节数 , 但在 stream 上下文中不可用 ; 
    #         如果强行使用 , Nginx 启动会报错或日志变量为空 ; 
    # 【用途】原计划记录 TCP 流量的入站和出站字节数 , 用于计费、监控、审计 ; 
    #         当前版本暂不使用 , 可通过其他监控工具 ( 如 iptables、tcpdump ) 替代 ; 
    # log_format tcp_log '$remote_addr [$time_local] $protocol $status $bytes_in $bytes_out $upstream_addr';
    # access_log logs/tcp_access.log tcp_log;

    # ======================================
    # Upstream 上游服务器组定义
    # 【核心原理】upstream 定义一组后端服务器 , Nginx 可实现负载均衡、故障转移、健康检查 ; 
    #            支持多种调度算法: 轮询 (round-robin, 默认)、ip_hash、least_conn 等 ; 
    #            当某个后端节点故障时 , Nginx 会自动将流量切换到健康节点 ; 
    # ======================================
    upstream tcp_backend {
        # 【配置项】server 39.156.70.239:8082;
        # 【原理】定义一个后端 TCP 服务节点 , Nginx 将客户端的 TCP 连接转发至此地址和端口 ; 
        #         默认使用轮询算法 , 每来一个连接分配给下一个可用节点 ; 
        #         可附加参数: weight=5 (权重)、max_fails=3 (最大失败次数)、fail_timeout=30s (故障判定时间)、backup (备用节点) 等 ; 
        # 【用途】指向真实的 TCP 后端服务 , 此处为公网服务器 39.156.70.239 的 8082 端口 , 用于承载自定义 TCP 业务 ( 如 808 协议网关 )  ; 
        server 39.156.70.239:8082;
    }

    # ======================================
    # TCP 监听服务定义 (server 上下文)
    # 【核心原理】Nginx 在此端口上监听传入的 TCP 连接 , 建立客户端与后端之间的双向管道 ; 
    #            数据在客户端 socket 和 upstream socket 之间直接转发 , Nginx 充当透明代理 ; 
    # ======================================
    server {
        # 【配置项】listen 8082;
        # 【原理】绑定本机 (0.0.0.0) 的 8082 端口 , 开始监听传入的 TCP 连接请求 ; 
        #         操作系统内核的 TCP/IP 协议栈将三次握手后的连接交给 Nginx 的 worker 进程处理 ; 
        #         可附加参数: reuseport (多核负载均衡)、ssl (启用 TLS)、udp (UDP 模式) 等 ; 
        # 【用途】对外暴露 TCP 代理入口 , 客户端设备 ( 如物联网终端 ) 连接此端口 , 流量被转发到后端真实服务 ; 
        #         与后端端口保持一致 ( 均为 8082 )  , 便于端口映射和防火墙规则管理 ; 
        listen 8082;

        # 【配置项】proxy_pass tcp_backend;
        # 【原理】将当前接收到的 TCP 连接完整转发到名为 "tcp_backend" 的 upstream 组 ; 
        #         Nginx 在客户端和后端之间建立全双工数据通道 , 字节流透明传输 ; 
        #         与 HTTP 的 proxy_pass 不同 , stream 的 proxy_pass 不解析 HTTP 头 , 直接转发原始 TCP 数据 ; 
        # 【用途】实现四层负载均衡和反向代理 , 隐藏后端真实服务器 , 提供统一的接入入口 ; 
        proxy_pass tcp_backend;

        # 【配置项】proxy_connect_timeout 10s;
        # 【原理】Nginx 作为代理 , 需要主动连接后端 upstream 服务器 ; 
        #         此参数设定建立与后端 TCP 连接的最长等待时间 ; 
        #         如果 10 秒内无法与后端建立 TCP 三次握手 , Nginx 会向客户端返回连接失败并记录错误日志 ; 
        # 【用途】防止后端服务宕机或网络不通时 , Nginx 无限等待导致客户端长时间挂起 ; 
        #         10 秒是较为宽松的设置 , 内网环境可缩短至 3-5 秒 ; 
        proxy_connect_timeout 10s;

        # 【配置项】proxy_timeout 3600s;
        # 【原理】当 TCP 连接建立后 , 如果 3600 秒内连接上没有任何数据传输 ( 双向均无数据 )  , 
        #         Nginx 会自动断开此连接 , 释放系统资源 ( socket、内存、文件描述符 )  ; 
        #         此机制称为 "空闲超时" (idle timeout) , 区别于整体连接超时 ; 
        # 【用途】3600 秒 = 1 小时 , 适配需要长时间保活的场景 ( 如物联网设备心跳间隔较长 )  ; 
        #         防止客户端异常断网但 TCP 连接未正常关闭时产生的 "僵尸连接" 长期占用资源 ; 
        proxy_timeout 3600s;

        # 【配置项】tcp_nodelay on;
        # 【原理】TCP 协议默认启用 Nagle 算法 , 该算法会将小数据包合并后发送 , 以减少网络拥塞 ; 
        #         但合并过程会引入延迟 ( 通常 40-200ms )  , 对实时性要求高的场景不利 ; 
        #         tcp_nodelay on 禁用 Nagle 算法 , 数据到达后立即发送 , 降低延迟 ; 
        #         代价是可能增加小包数量 , 消耗更多网络带宽和 CPU ; 
        # 【用途】对实时数据传输 ( 如物联网指令下发、即时消息 ) 至关重要 , 确保最小传输延迟 ; 
        #         如果传输的是大文件或批量数据 , 可关闭此选项以提高吞吐量 ; 
        tcp_nodelay on;

        # 【配置项】proxy_buffer_size 4k;
        # 【原理】Nginx 在转发 TCP 数据时使用内存缓冲区暂存数据 ; 
        #         缓冲区越大 , 每次系统调用可传输的数据越多 , CPU 开销越低 , 但内存占用越高 ; 
        #         4k 是系统内存页的典型大小 , 与内核分页机制对齐 , 减少内存碎片 ; 
        # 【用途】平衡内存占用与传输效率 , 4k 适合中小型数据包场景 ( 如 JSON、二进制指令 )  ; 
        #         如果传输大文件 , 可增大至 16k 或 32k ; 内存受限环境可减小至 1k ; 
        proxy_buffer_size 4k;
    }
}

# ==========================================
# HTTP 七层代理模块
# 【核心原理】在 OSI 网络模型的应用层 ( 第7层 ) 工作 , 完整解析 HTTP/HTTPS 协议 ; 
#            可读取 HTTP 请求头、请求体、响应头 , 实现路由、重写、缓存、负载均衡、SSL 终止等高级功能 ; 
#            WebSocket 协议虽然基于 TCP , 但握手阶段使用 HTTP , 因此也在 http 模块中配置 ; 
# ==========================================
http {
    # 【配置项】include mime.types;
    # 【原理】Nginx 通过 MIME 类型 ( Multipurpose Internet Mail Extensions ) 告知浏览器响应内容的格式 ; 
    #         mime.types 文件包含数百种文件扩展名与 Content-Type 的映射关系 ( 如 .html → text/html, .json → application/json )  ; 
    #         当 Nginx 直接提供静态文件时 , 根据文件扩展名自动设置正确的 Content-Type 响应头 ; 
    # 【用途】确保浏览器正确解析和渲染返回的内容 , 避免文件被误下载或显示为乱码 ; 
    #         路径是相对 Nginx 安装目录的 conf/mime.types ; 
    include mime.types;

    # 【配置项】default_type application/octet-stream;
    # 【原理】当请求的文件扩展名在 mime.types 中找不到对应类型时 , 使用此默认值 ; 
    #         application/octet-stream 表示 "未知二进制流" , 浏览器通常会弹出下载对话框 ; 
    #         这是一种安全保守的设定 , 防止未知文件类型被浏览器错误执行 ; 
    # 【用途】适配自定义接口返回的二进制数据 ( 如 808 协议封装、Protobuf、加密数据包 )  ; 
    #         确保即使文件类型未知 , 也不会被浏览器当作文本或脚本处理 ; 
    default_type application/octet-stream;

    # ======================================
    # 日志格式定义
    # 【核心原理】Nginx 支持自定义访问日志格式 , 通过变量捕获每次请求的详细信息 ; 
    #            变量以 $ 开头 , 由 Nginx 内核在请求处理过程中动态计算 ; 
    # ======================================
    # 【配置项】log_format main ...
    # 【原理】定义名为 "main" 的日志格式模板 , 采用类 Apache 的 combined 日志格式 ; 
    #         各变量含义:
    #         $remote_addr      --- 客户端真实 IP 地址 ( 如果经过多层代理 , 可能是最后一层代理的 IP ) 
    #         $remote_user      --- HTTP Basic 认证的用户名 ( 未认证时为 - ) 
    #         $time_local       --- 服务器本地时间 , 格式为 [24/Jun/2026:14:30:00 +0800]
    #         $request          --- 完整的 HTTP 请求行 , 如 "GET /api/status HTTP/1.1"
    #         $status           --- HTTP 响应状态码 , 如 200、404、500
    #         $body_bytes_sent  --- 响应体字节数 ( 不含响应头 )  , 用于计算实际传输流量
    #         $http_referer     --- 请求来源页面 URL , 用于分析流量来源和防盗链
    #         $http_user_agent  --- 客户端浏览器/APP 标识 , 如 "Mozilla/5.0..." 或 "Dart/3.0"
    #         $http_x_forwarded_for --- 代理链传递的原始客户端 IP ( 多层代理场景关键 ) 
    # 【用途】生成标准化的访问日志 , 用于流量分析、安全审计、故障排查、用户行为统计 ; 
    #         可与 ELK (Elasticsearch + Logstash + Kibana) 或 GoAccess 等工具配合可视化分析 ; 
    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 logs/http_ws_access.log main;
    # 【原理】将符合 "main" 格式的访问日志写入指定文件 ; 
    #         每条请求 ( 无论成功或失败 ) 在处理完成后生成一条日志记录 ; 
    #         日志文件支持按时间或大小切割 ( 通过 logrotate 或 Nginx 的 reopen 信号 )  ; 
    # 【用途】HTTP 和 WebSocket 共用此日志文件 , 统一记录七层应用访问情况 ; 
    #         通过分析日志可发现异常请求、性能瓶颈、攻击行为 ( 如爬虫、暴力破解 )  ; 
    access_log logs/http_ws_access.log main;

    # ======================================
    # 传输优化配置
    # ======================================
    # 【配置项】sendfile on;
    # 【原理】sendfile 是 Linux 内核提供的高效文件传输系统调用 ; 
    #         传统方式: 磁盘 → 内核缓冲区 → 用户空间 → 内核 socket 缓冲区 → 网卡 ( 4次拷贝 )  ; 
    #         sendfile: 磁盘 → 内核缓冲区 → 网卡 ( 2次拷贝 , 零拷贝技术 )  ; 
    #         完全绕过用户空间 , 减少 CPU 占用和内存带宽消耗 ; 
    # 【用途】极大提升静态文件 ( 如图片、视频、JS/CSS ) 的传输效率 , 降低服务器负载 ; 
    #         对代理转发场景无直接影响 , 但 Nginx 直接返回文件时效果显著 ; 
    sendfile on;

    # 【配置项】keepalive_timeout 60;
    # 【原理】HTTP/1.1 支持长连接 (Keep-Alive) , 一个 TCP 连接可连续发送多个 HTTP 请求 ; 
    #         此参数设定连接空闲 ( 无新请求 ) 60 秒后 , Nginx 主动关闭连接 ; 
    #         长连接避免了每个请求都进行 TCP 三次握手和 TLS 握手的开销 , 显著降低延迟 ; 
    # 【用途】60 秒是通用平衡值 , Web 浏览器场景足够复用连接加载页面资源 ; 
    #         对高并发 API 服务可适当缩短 ( 如 30 秒 )  , 减少空闲连接占用的文件描述符 ; 
    keepalive_timeout 60;

    # 【配置项】client_max_body_size 100M;
    # 【原理】限制客户端请求体 ( POST/PUT 上传的文件或数据 ) 的最大大小 ; 
    #         超过此限制的请求 , Nginx 直接返回 413 Request Entity Too Large 错误 , 不会转发到后端 ; 
    #         这是重要的安全防线 , 防止恶意用户上传超大文件耗尽服务器磁盘和内存 ; 
    # 【用途】100MB 适配大文件上传场景 ( 如图片批量上传、日志文件上报 )  ; 
    #         如果业务不需要大文件上传 , 建议设为 1M-10M 以减小攻击面 ; 
    client_max_body_size 100M;

    # ======================================
    # WebSocket 代理通用头部配置
    # 【核心原理】WebSocket 协议握手阶段使用 HTTP/1.1 的 Upgrade 机制 ; 
    #            客户端发送带有 "Upgrade: websocket" 和 "Connection: Upgrade" 的请求头 ; 
    #            服务器返回 101 Switching Protocols 后 , 连接从 HTTP 模式升级为全双工 WebSocket 模式 ; 
    #            此后数据以帧 (frame) 形式传输 , 不再使用 HTTP 语义 ; 
    #            代理服务器必须原样透传这些头部 , 否则握手会失败 ; 
    # ======================================

    # 【配置项】proxy_http_version 1.1;
    # 【原理】HTTP/1.0 不支持 Upgrade 机制 , 必须使用 HTTP/1.1 才能建立 WebSocket 连接 ; 
    #         Nginx 默认向后端使用 HTTP/1.0 , 显式设置为 1.1 以支持 WebSocket 握手 ; 
    # 【用途】确保与后端服务器的 WebSocket 握手兼容 , 是 WebSocket 代理的基础配置 ; 
    proxy_http_version 1.1;

    # 【配置项】proxy_set_header Upgrade $http_upgrade;
    # 【原理】$http_upgrade 是 Nginx 内置变量 , 取值为客户端请求头 "Upgrade" 的值 ( WebSocket 请求中为 "websocket" )  ; 
    #         将此头部原样传递给后端服务器 , 告知后端客户端希望升级协议 ; 
    # 【用途】协议升级协商的关键头部 , 缺失或错误会导致后端返回 400/404 错误 , WebSocket 连接无法建立 ; 
    proxy_set_header Upgrade $http_upgrade;

    # 【配置项】proxy_set_header Connection "upgrade";
    # 【原理】HTTP/1.1 默认 Connection: keep-alive , 但 WebSocket 握手需要 Connection: upgrade ; 
    #         此配置强制将 Connection 头部设为 "upgrade" 传递给后端 ; 
    # 【用途】与 Upgrade 头部配合使用 , 完成协议升级的必要条件 ; 某些后端框架 ( 如 Node.js ws、Spring WebSocket ) 严格依赖此头部 ; 
    proxy_set_header Connection "upgrade";

    # 【配置项】proxy_set_header Host $host;
    # 【原理】$host 变量取自客户端请求头 "Host" 的值 ( 如 "api.example.com:8080" )  ; 
    #         将原始 Host 头部传递给后端 , 使后端服务器能正确识别虚拟主机 ; 
    # 【用途】多域名/多租户场景必备 , 后端根据 Host 路由到正确的应用实例 ; 
    #         如果不传递 , 后端可能使用默认站点 , 导致路由错误或 SSL 证书不匹配 ; 
    proxy_set_header Host $host;

    # 【配置项】proxy_set_header X-Real-IP $remote_addr;
    # 【原理】由于 Nginx 代理后 , 后端看到的客户端 IP 会变成 Nginx 服务器的 IP ( 如 127.0.0.1 )  ; 
    #         通过自定义头部 X-Real-IP 将真实客户端 IP 传递给后端应用 ; 
    # 【用途】后端应用 ( 如 Java、PHP、Node.js ) 可读取此头部记录用户真实 IP , 用于日志、限流、地理位置分析 ; 
    #         单级代理场景直接使用 , 多级代理需配合 X-Forwarded-For ; 
    proxy_set_header X-Real-IP $remote_addr;

    # 【配置项】proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    # 【原理】$proxy_add_x_forwarded_for 变量会取出客户端请求中的 X-Forwarded-For 头部 ( 如果有 )  , 
    #         并在末尾追加当前连接的 $remote_addr , 形成完整的代理链 IP 列表 ; 
    #         格式: "客户端IP, 代理1IP, 代理2IP, ..."
    # 【用途】多级代理场景下追溯原始客户端 IP 的标准方案 , 被几乎所有 Web 框架支持 ; 
    #         相比 X-Real-IP , 能记录完整的代理链路 , 防止 IP 伪造 ( 需结合第一层代理的信任配置 )  ; 
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    # ======================================
    # HTTP 转发服务: 本机 8080 → 后端 39.156.70.239:8080
    # 【核心原理】接收本机 8080 端口的 HTTP 请求 , 反向代理到后端服务器的 8080 端口 ; 
    #            Nginx 解析 HTTP 请求 , 可基于 URL、方法、头部做路由 , 然后转发到对应后端 ; 
    # ======================================
    upstream http_backend {
        # 【配置项】server 39.156.70.239:8080;
        # 【原理】定义 HTTP 后端服务器节点 , Nginx 使用轮询算法分发请求 ; 
        #         支持健康检查: 当后端返回 502/503/504 或连接失败时 , 自动标记为 down , 后续请求不再分发 ; 
        # 【用途】指向提供 HTTP REST API 的后端服务 ( 如 Spring Boot、Django、Flask 应用 )  , 实现负载均衡和高可用 ; 
        server 39.156.70.239:8080;
    }

    server {
        # 【配置项】listen 8080;
        # 【原理】绑定本机 8080 端口 , 监听传入的 HTTP 连接 ; 
        #         Nginx 接收 HTTP 请求后 , 根据 location 规则决定如何处理 ; 
        # 【用途】对外暴露 HTTP API 入口 , Flutter APP、Web 前端、第三方系统通过此端口调用后端接口 ; 
        listen 8080;

        # 【配置项】server_name _;
        # 【原理】server_name 用于虚拟主机匹配 , 基于 HTTP 请求头 "Host" 的值选择对应的 server 块 ; 
        #         "_" 是一个无效的域名占位符 , 表示匹配任何 Host 头部 ( 默认 catch-all )  ; 
        #         当没有其他 server_name 能匹配时 , 此 server 块处理请求 ; 
        # 【用途】简化配置 , 不区分域名 , 直接通过端口号区分服务 ; 适合内网或 IP 直接访问的场景 ; 
        server_name _;

        # 【配置项】location / { ... }
        # 【原理】location 是 Nginx 最核心的指令 , 根据请求的 URI 路径匹配处理规则 ; 
        #         "/" 是最通用的匹配规则 , 匹配所有 URI 路径 ( 如果没有更具体的匹配规则 )  ; 
        #         匹配优先级: 精确匹配 (=) > 前缀匹配 (^~) > 正则匹配 (~ ~*) > 通用匹配 (/) ; 
        # 【用途】将所有 HTTP 请求统一转发到 http_backend , 不区分具体路径 ; 
        #         如需针对 /api、/static 等不同路径做不同处理 , 可添加多个 location 块 ; 
        location / {
            # 【配置项】proxy_pass http://http_backend;
            # 【原理】将当前 HTTP 请求完整转发到 http_backend upstream 组 ; 
            #         Nginx 会重新构建 HTTP 请求发送给后端 , 然后将后端响应返回给客户端 ; 
            #         URL 拼接规则: proxy_pass 末尾无斜杠时 , 原始 URI 原样附加 ; 有斜杠时 , 替换 location 匹配部分 ; 
            # 【用途】实现 HTTP 反向代理 , 隐藏后端真实地址 , 提供统一的 API 网关入口 ; 
            proxy_pass http://http_backend;

            # 【配置项】proxy_read_timeout 30s;
            # 【原理】Nginx 等待后端服务器返回响应的超时时间 ; 
            #         从发送完请求到接收完响应头的整个过程计时 ; 
            #         如果后端在 30 秒内没有返回任何数据 , Nginx 返回 504 Gateway Timeout 给客户端 ; 
            # 【用途】30 秒适配大多数 API 接口响应时间 , 防止后端卡死时 Nginx 无限等待 ; 
            #         如果后端有耗时操作 ( 如大数据导出 )  , 需适当增大 ; 
            proxy_read_timeout 30s;

            # 【配置项】proxy_send_timeout 30s;
            # 【原理】Nginx 向后端服务器发送请求数据的超时时间 ; 
            #         主要针对 POST/PUT 上传大文件场景 , 确保发送过程不会因为网络抖动而中断 ; 
            # 【用途】与 proxy_read_timeout 配对使用 , 确保请求双向传输都有合理的超时控制 ; 
            proxy_send_timeout 30s;
        }
    }

    # ======================================
    # WebSocket 转发服务: 本机 8081 → 后端 39.156.70.239:8081
    # 【核心原理】WebSocket 建立后 , 连接保持长连接状态 , 双向实时推送数据 ; 
    #            与 HTTP 短连接不同 , WebSocket 连接可能持续数小时甚至数天 ; 
    #            因此超时设置需要远大于 HTTP 服务 , 避免频繁断开重连 ; 
    # ======================================
    upstream ws_backend {
        # 【配置项】server 39.156.70.239:8081;
        # 【原理】定义 WebSocket 后端服务器节点 , 与 HTTP upstream 机制相同 ; 
        #         WebSocket 握手成功后 , 连接升级为长连接 , upstream 的负载均衡在连接建立时即确定 ; 
        #         同一 WebSocket 连接内的所有数据帧都发往同一后端节点 ( 会话粘性 )  ; 
        # 【用途】指向提供 WebSocket 服务的后端 ( 如基于 Socket.io、ws、netty-websocket 的服务 )  ; 
        #         用于实时消息推送、设备状态同步、在线客服、股票行情等场景 ; 
        server 39.156.70.239:8081;
    }

    server {
        # 【配置项】listen 8081;
        # 【原理】绑定本机 8081 端口 , 专门用于接收 WebSocket 连接 ; 
        #         WebSocket 握手阶段的请求与普通 HTTP 请求格式相同 , Nginx 通过 location 规则处理 ; 
        # 【用途】为 Flutter APP 或其他客户端提供独立的 WebSocket 接入端口 , 与 HTTP API 分离 , 便于独立监控和限流 ; 
        listen 8081;

        # 【配置项】server_name _;
        # 【原理】同 HTTP 服务 ,  catch-all 匹配任意 Host 头部 ; 
        # 【用途】简化配置 , 不校验域名 , 直接通过端口号识别 WebSocket 服务 ; 
        server_name _;

        location / {
            # 【配置项】proxy_pass http://ws_backend;
            # 【原理】将 WebSocket 握手请求转发到 ws_backend , 握手成功后保持长连接 ; 
            #         与 HTTP proxy_pass 使用相同的指令 , 但结合上方的 Upgrade/Connection 头部配置实现协议升级 ; 
            #         升级成功后 , Nginx 不再解析 HTTP , 仅在客户端和后端之间透传 WebSocket 数据帧 ; 
            # 【用途】建立并维持客户端与后端 WebSocket 服务的长连接 , 支持双向实时通信 ; 
            proxy_pass http://ws_backend;

            # 【配置项】proxy_read_timeout 3600s;
            # 【原理】WebSocket 长连接可能长时间无数据传输 ( 如仅维持心跳 )  ; 
            #         3600 秒 = 1 小时的超时设置 , 确保不会因为空闲而被 Nginx 断开 ; 
            #         注意: 此超时后 Nginx 会发送 CLOSE 帧优雅关闭连接 , 不是强制 RST ; 
            # 【用途】适配需要长期在线的场景 ( 如物联网设备实时监控、IM 消息长连接 )  ; 
            #         如果后端有心跳机制 ( 如每 30 秒 ping/pong )  , 可适当缩短至 120 秒 ; 
            proxy_read_timeout 3600s;

            # 【配置项】proxy_send_timeout 3600s;
            # 【原理】与 proxy_read_timeout 对称 , 控制向后端发送数据的超时 ; 
            #         WebSocket 推送消息时 , 如果后端接收缓慢 , Nginx 会等待此超时时间 ; 
            # 【用途】与 proxy_read_timeout 保持一致 , 确保 WebSocket 长连接的双向通信都有充足的超时时间 ; 
            proxy_send_timeout 3600s;
        }
    }
}