Nginx中server块与location是严格分层的两级路由:listen决定请求进入哪个虚拟主机,location在选定server内匹配URI;server未匹配则location不生效。

Nginx 中 server 块监听端口与 location 的配合,核心在于“先定服务、再定路径”——listen 决定请求进哪个虚拟主机,location 决定该主机内如何处理具体 URI。两者不是并列关系,而是严格分层的两级路由:没有匹配的 server 块,location 根本不会被触发;server 一旦选定,所有 location 规则才开始参与 URI 匹配。
listen 是入口守门员:端口和 IP 决定谁能进门
每个 server 块必须通过 listen 明确声明它愿意响应哪些网络连接。Nginx 启动时会为每个 listen 创建独立监听套接字(如 0.0.0.0:80、127.0.0.1:8821 或 [::]:443)。当请求到达,内核按 TCP 五元组把连接分发给对应 socket,只有绑定该 socket 的 server 块才有资格继续处理。
- 端口必须完全一致:请求发到 8821,就只看 listen 8821 的 server 块,哪怕其他块写了
server_name localhost也无效 - IP 更精确优先:
listen 192.168.1.100:80比listen *:80匹配度更高;若都匹配且端口相同,Nginx 选 IP 更具体的那个 - 没写 listen 的 server 块会被补成
listen *:80(root 用户)或*:8080(普通用户),容易引发意外交互
server_name 是二次筛选器:在同端口多个 server 间做域名分流
当多个 server 块监听同一端口(比如都是 listen 80),Nginx 才会读取请求头里的 Host 字段,用 server_name 做进一步区分。
- 完全匹配最高:Host =
api.example.com→server_name api.example.com立刻命中 - 通配符有方向性:
*.example.com匹配foo.example.com,但不匹配example.com;example.*匹配example.net - 正则最慢也最后:
~^www\.(.+)$只在前面所有方式都不匹配时才尝试 - 没匹配上?走带
default_server标记的块;没标就用该端口第一个定义的 server 块
location 是路径调度员:在选定的 server 内精准分发请求
一旦 server 块确定,Nginx 就根据请求的 URI(不含域名和参数)逐条比对它的 location 规则,规则之间有明确优先级:
-
location = /health:精确匹配,最快,只认/health这个完整字符串 -
location ^~ /static/:前缀匹配且禁止正则后续检查,适合静态资源目录 -
location /api/:普通前缀匹配,最长前缀胜出(/api/v1会进这里,不是/api) -
location ~ \.(js|css|png)$:区分大小写的正则,常用于设置缓存头或拒绝访问 - 正则按配置顺序执行,第一个匹配即停止,不回溯
典型配合场景示例
比如想让 http://localhost:8821/fddd?app=test 走流媒体逻辑,而根路径返回提示页:
- 用独立
server { listen 8821; }隔离端口,避免和主站 80/443 混淆 - 不需要
server_name,因为 8821 端口通常只配一个 server 块,Host 头不参与决策 -
location /放默认响应,location /fddd专用于流处理,用chunked_transfer_encoding on支持直播流 - 如果未来要支持多域名共用 8821,再加
server_name fddd.example.com和对应location即可


















