Skip to content

Nginx:静态站点与反向代理配置 · 请求行为矩阵与失败预期至实践练习与参考解答 ​

返回分篇目录

本篇以Nginx 静态站与代理为例;前置是主配置、conf_prefix、Host/SNI 和上游地址。源码与输入与下文配置共用同一份文件,示例未执行。

前置为路径与代理语义。示例未执行;Nginx配置未由nginx -t检验。

请求行为矩阵与失败预期 ​

Nginx 请求行为需要同时核对客户端状态、上游目标与日志来源,不能只看到200就判断路由正确。以下是设计预期,尚未发送这些请求:

请求(Host为lab.local)预期解释
GET /200根页面index处理公开首页
GET /missing404普通静态位置try_files结束
GET /app/lesson200应用壳内部重定向到/app/index.html
GET /download/guide.txt200文本精确alias映射固定文件
GET /.git/config404隐藏路径正则拒绝
GET /api308固定跳转到/api/,不拼Host
GET /api/status?mode=brief200 JSON上游收到/status?mode=brief
GET /api/fail503 JSON上游有意拒绝,代理不重试
GET /api/slow504预期等待响应头超过5秒
GET /api/status,上游未启动502连接被拒绝,须看error.log
GET /healthz,上游未启动200只证明入口存活
任一路径,Host为unknown404默认server拒绝

上游关闭、操作系统调度和客户端取消可能改变故障细节,具体状态以未来实测日志为准。HEAD不应有响应体;读取请求头、发送头、客户端断开也可能发生在设计超时之前。

读者自跑、TLS与清理 ​

Nginx 自跑步骤只为读者提供,当前未执行。README完整列出复制前提、普通用户启动、nginx -t、请求对照和按相同prefix优雅退出的命令。不要在已有系统实例里试错,不使用全局进程终止。TLS可选主配置与HTTP配置共用PID,因此先停止一套再启动另一套。

md
# Nginx 理论示例(未执行)

只提供文件与预期行为,不是运行验收。Nginx 配置未由 nginx -t 检验;AST/JSON/模板检查不能证明指令、权限、模块、TLS 或网络正确。

依赖:Linux 用户空间、已由读者安装的受维护 Nginx Open Source(本文按1.28/1.29族共同指令解释)、下文 /api 反向代理步骤还需要已安装的 Node.js >=22 来运行 upstream.mjs;仅查看静态文件配置时不需要 Node.js。没有 npm 依赖,无需 npm install。TLS另要求http_ssl模块、支持TLS1.3的OpenSSL以及读者合法取得的证书链和匹配私钥。此目录不含证书或私钥。Windows原生Nginx是官方beta实现,配置需要自行替换绝对路径并检查模块;不将Linux运行方式称为Windows已验证。

以下是读者以后自跑的Linux shell说明,本轮没有执行:

```sh
# 从仓库根目录开始;目标必须不存在,避免覆盖任何已有环境。
test ! -e /tmp/m5-nginx || exit 1
cp -R examples/m5-nginx /tmp/m5-nginx
mkdir -p /tmp/m5-nginx/logs /tmp/m5-nginx/temp/client /tmp/m5-nginx/temp/proxy
# 以普通用户运行;8088、9088必须空闲,目录归该用户,不使用sudo。
node /tmp/m5-nginx/upstream.mjs
```

保留上游前台窗口,在另一个终端进行下一组操作:

```sh
nginx -p /tmp/m5-nginx/ -c nginx.conf -t
nginx -p /tmp/m5-nginx/ -c nginx.conf
curl --fail-with-body -H 'Host: lab.local' http://127.0.0.1:8088/
curl --fail-with-body -H 'Host: lab.local' 'http://127.0.0.1:8088/api/status?mode=brief'
```

读者应检查根页200、/app/lesson应用壳200、/missing为404、/download/guide.txt固定文件200、/.git/config为404、Host: unknown为404。只读API收到/status?mode=brief,返回ok=true;/api/fail预期503,/api/slow预期504(Nginx先等待5秒超时),上游未启动时/api/status预期502。/healthz仅证明Nginx响应,不证明上游健康。每次保留access.jsonl与error.log,对照课程诊断。

可选TLS:读者创建certs目录,将签发给lab.local且在有效期内的完整链命名lab-fullchain.pem、对应私钥命名lab-key.pem,并按运行用户最小可读设置私钥权限;本仓库不提供证书生成命令。先退出HTTP实例,再对nginx-tls.conf执行同样的-t及启动步骤,不能两套主配置同时运行,因为共享PID与日志。客户端用可信CA文件与curl --resolve lab.local:8443:127.0.0.1 --cacert /绝对路径/lab-ca.pem https://lab.local:8443/;不要用-k替代信任链验证。未知SNI预期握手被拒绝。

清理:读者对自己启动的前缀执行nginx -p /tmp/m5-nginx/ -c nginx.conf -s quit(TLS时换对应主配置),在上游窗口按Ctrl+C,确认专用进程结束,归档日志后只删除自己创建的/tmp/m5-nginx目录。不要使用全局pkill或删除其他Nginx配置。reload、reopen和quit必须指向相同前缀/PID,不能混用系统服务与这个教学实例。
nginx
worker_processes 1;
pid logs/nginx.pid;
error_log logs/error.log warn;
events { worker_connections 256; }
http {
    include conf/http-common.conf;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_session_cache shared:LABTLS:1m;
    ssl_session_tickets off;
    server {
        listen 127.0.0.1:8443 ssl default_server;
        ssl_reject_handshake on;
        return 404;
    }
    server {
        listen 127.0.0.1:8443 ssl;
        server_name lab.local;
        ssl_certificate certs/lab-fullchain.pem;
        ssl_certificate_key certs/lab-key.pem;
        include conf/site.conf;
    }
}

实践练习与参考解答 ​

练习:不启动服务,画出/api/status、/app/lesson与/download/guide.txt各自经过的文件和处理器,说明为什么只有第一个请求需要Node进程。

参考解答:三个请求先经nginx.conf选择lab.local,再进入site.conf;API去lab_backend并替换前缀,app经try_files内部重定向至root内的应用壳,download直接命中精确alias。后两者由Nginx读文件,无Node依赖。以后读者验收要同时确认静态缺失404和上游缺失404来源不同,而非只验成功首页。

继续阅读