配置静态 Web 服务器
静态 Web 服务器的主要功能由 ngx_http_core_module 模块实现,完整的静态 Web 服务器还会包含多个 server 块和 location 块。
Nginx 配置完整的静态 Web 服务器包含以下 8 类配置:
| 配置类别 | 说明 |
|---|---|
| 虚拟主机与请求分发 | 监听端口、主机名称、location 匹配 |
| 文件路径定义 | root、alias、index、error_page |
| 内存及磁盘资源分配 | 缓冲区大小、临时文件路径 |
| 网络连接设置 | 连接超时、缓冲区配置 |
| MIME 类型设置 | 文件类型映射、默认类型 |
| 对客户端请求的限制 | 请求大小、速率限制 |
| 文件操作优化 | sendfile、缓存、压缩 |
| 对客户端请求特殊处理 | 请求头处理、重写规则 |
虚拟主机与请求分发
由于 IP 地址数量有限,多个主机域名可能对应同一个 IP。Nginx 通过 server_name 和 server 块定义虚拟主机,实现同一服务器以不同方式处理不同域名的请求。
监听端口
默认:listen 80;
listen 决定 Nginx 监听的端口和地址,支持多种格式:
# IPv4 地址
listen 127.0.0.1:8000;
listen 127.0.0.1; # 默认监听 80 端口
listen 8000;
listen *:8000;
listen localhost:8000;
# IPv6 地址
listen [::]:8000;
listen [fe80::1];
listen [:::a8c9:1234]:80;
# 带参数
listen 443 default_server ssl;
listen 127.0.0.1 default_server accept_filter=dataready backlog=1024;listen 可用参数:
| 参数 | 说明 |
|---|---|
default / default_server | 将该 server 设为默认虚拟主机,处理无法匹配的请求 |
backlog=num | TCP 中 backlog 队列大小,默认 -1 表示不设置 |
rcvbuf=size | 设置监听句柄的 SO_RCVBUF 参数 |
sndbuf=size | 设置监听句柄的 SO_SNDBUF 参数 |
accept_filter | 设置 accept 过滤器(仅 FreeBSD) |
deferred | 延迟 worker 唤醒,直到收到请求数据(适合高并发) |
bind | 绑定当前端口/地址对(仅监听多个地址时生效) |
ssl | 当前端口必须使用 SSL 协议 |
主机名称
语法:server_name name[...];
server_name 可跟多个主机名称,如 server_name www.testweb.com download.testweb.com;。
Nginx 取出请求 Header 中的 Host 与 server_name 匹配,决定由哪个 server 处理请求。
匹配优先级:
| 优先级 | 匹配方式 | 示例 |
|---|---|---|
| 1(最高) | 完全匹配 | www.testweb.com |
| 2 | 通配符在前 | *.testweb.com |
| 3 | 通配符在后 | www.testweb.* |
| 4 | 正则表达式 | ~^\.testweb\.com$ |
Server 名称哈希配置
| 配置项 | 语法 | 默认值 | 说明 |
|---|---|---|---|
| 哈希桶大小 | server_names_hash_bucket_size size; | 32|64|128 | 每个散列桶占用的内存大小 |
| 最大哈希大小 | server_names_hash_max_size size; | 512 | 影响散列冲突率,越大冲突越低但消耗内存越多 |
重定向主机名称
语法:server_name_in_redirect on|off; 默认:on
配置块:http、server、location
| 值 | 说明 |
|---|---|
on | 重定向时使用 server_name 第一个主机名 |
off | 重定向时使用请求中的 Host 头部 |
Location 匹配
语法:location [=\|~\|~*\|^~\|@] /uri/ { ... }
配置块:server
Location 根据 URI 匹配决定使用哪个配置块处理请求。
匹配优先级:
| 优先级 | 修饰符 | 类型 | 说明 |
|---|---|---|---|
| 1(最高) | = | 精确匹配 | 完全相等时匹配 |
| 2 | ^~ | 前缀匹配 | 匹配后停止正则检查 |
| 3 | ~ | 正则匹配 | 区分大小写 |
| 4 | ~* | 正则匹配 | 不区分大小写 |
| 5 | 无修饰符 | 前缀匹配 | 普通前缀匹配 |
| 6(最低) | / | 通用匹配 | 匹配所有请求 |
示例:
server {
listen 80;
server_name example.com;
# 精确匹配
location = /login {
return 200 "Exact: Login page";
}
# 前缀匹配(不检查正则)
location ^~ /static/ {
return 200 "Prefix: Static files";
}
# 正则匹配(区分大小写)
location ~ \.(php|php5)$ {
return 200 "Regex: PHP files";
}
# 正则匹配(不区分大小写)
location ~* \.(jpg|JPG)$ {
return 200 "Case-insensitive: JPG files";
}
# 普通前缀匹配
location /api/ {
return 200 "General prefix match!";
}
}- 其次选择通配符在前面的 server_name,如
*.testweb.com - 再次选择通配符在后面的 server_name,如
www.testweb.* - 最后选择使用正则表达式才匹配的 server_name,如
~^\.testweb\.com$
server_names_hash_bucket_size
语法:server_names_hash_bucket_size size;。 默认:server_names_hash_bucket_size 32|64|128;
配置块:http、server、location
为提高快速寻找到相应 server name 的能力,Nginx 使用散列表来存储 server name。server_names_hash_bucket_size 设置每个散列桶占用的内存大小
server_names_hash_max_size
语法:server_names_hash_max_size size;。 默认:server_names_hash_max_size 512;
配置块:http、server、location
server_names_hash_max_size 会影响散列表的冲突率。server_names_hash_max_size 越大,消耗的内存就越多,但散列 key 的冲突率则会降低,检索速度也更快。server_names_hash_max_size 越小,消耗的内存就越小,但散列 key 的冲突率可能增高
重定向主机名称的处理
语法:server_name_in_redirect on|off;。默认:server_name_in_redirect on;
配置块:http、server 或者 location
该配置需要配合 server_name 使用。on 打开时,表示在重定向请求时会使用 server_name 里配置的第一个主机名代替原先请求中的 Host 头部,而使用 off 关闭时,表示在重定向请求时使用请求本身的 Host 头部
location
语法:location[=|~|~*|^~|@]/uri/{...}
配置块:server
location 会尝试根据用户请求中的 URI 来匹配上面的 /uri 表达式,如果可以匹配,就选择 location{} 块中的配置来处理用户请求。当然匹配方式是多样的
location [修饰符] 匹配模式 {
# 配置指令
}Nginx 按照以下优先级顺序匹配 location:
=精确匹配(最高优先级)^~前缀匹配(不检查正则)~和~\*正则匹配- 无修饰符前缀匹配(最低优先级)
server {
listen 80;
server_name example.com;
# 1. 精确匹配(最高优先级)
location = /login {
return 200 "Exact: Login page";
}
# 2. 前缀匹配(不检查正则)
location ^~ /static/ {
return 200 "Prefix: Static files";
}
# 3. 正则匹配(区分大小写)
location ~ \.(php|php5)$ {
return 200 "Regex: PHP files";
}
# 4. 正则匹配(不区分大小写)
location ~* \.(jpg|JPG)$ {
return 200 "Case-insensitive: JPG files";
}
# 5. 普通前缀匹配
location /api/ {
# 匹配以 /api/ 开头的路径
return 200 "General prefix match!";
}
}匹配优先级顺序表:
| 序号 | 修饰符 | 类型 | 优先级 | 说明 |
|---|---|---|---|---|
| 1 | location = /path | 精确匹配 | 最高 | 完全相等时匹配 |
| 2 | location ^~ /path/ | 前缀匹配 | 高 | 匹配后停止正则检查 |
| 3 | location ~ pattern | 正则匹配 | 中 | 区分大小写正则 |
| 4 | location ~* pattern | 正则匹配 | 中 | 不区分大小写正则 |
| 5 | location /path | 前缀匹配 | 低 | 普通前缀匹配 |
| 6 | location / | 通用匹配 | 最低 | 匹配所有请求 |
文件路径定义
Root 方式设置资源路径
语法:root path; 默认:root html;
配置块:http、server、location、if
定义资源文件相对于 HTTP 请求的根目录
location /download/ {
root /opt/web/html/;
}| 请求 URI | 实际返回的文件 |
|---|---|
/download/index/test.html | /opt/web/html/download/index/test.html |
location /download/ {
root /opt/web/html/;
}Alias 方式设置资源路径
语法:alias path;
配置块:location
Alias 设置文件资源路径,与 root 的区别在于对 location 后的 URI 参数的解读。
Root vs Alias 对比:
| 配置 | URI | root 结果 | alias 结果 |
|---|---|---|---|
location /conf/ { root /usr/local/nginx/; } | /conf/nginx.conf | /usr/local/nginx/conf/nginx.conf | - |
location /conf/ { alias /usr/local/nginx/conf/; } | /conf/nginx.conf | - | /usr/local/nginx/conf/nginx.conf |
# 使用 alias
location /conf {
alias /usr/local/nginx/conf/;
}
# 使用 root
location /conf {
root /usr/local/nginx/;
}使用正则表达式:
location ~ ^/test/(\w+)\.(\w+)$ {
alias /usr/local/nginx/$2/$1.$2;
}请求 /test/nginx.conf → 返回 /usr/local/nginx/conf/nginx.conf
访问首页
语法:index file...; 默认:index index.html;
配置块:http、server、location
访问 / 时返回的首页文件,按顺序尝试。
location / {
root /var/www;
index index.html index.htm index.php;
}错误页面重定向
语法:error_page code[code...] [=\|=answer-code] uri|@named_location
配置块:http、server、location、if
当请求返回指定错误码时,重定向到新的 URI。
error_page 404 /404.html;
error_page 502 503 504 /50x.html;
error_page 403 http://example.com/forbidden.html;
error_page 404 = @fetch;更改返回码:
error_page 404 =200 /empty.gif; # 返回 200
error_page 404 =403 /forbidden.gif; # 返回 403
error_page 404 = /empty.gif; # 由实际结果决定重定向到命名 location:
location / {
error_page 404 @fallback;
}
location @fallback {
proxy_pass http://backend;
}Try Files
语法:try_files path1 [path2] uri;
配置块:server、location
按顺序尝试访问路径,找到文件则直接返回,否则重定向到最后参数。
try_files /system/maintenance.html $uri $uri/index.html $uri.html @other;
location @other {
proxy_pass http://backend;
}| 尝试顺序 | 路径 | 说明 |
|---|---|---|
| 1 | /system/maintenance.html | 维护页面 |
| 2 | $uri | 原始 URI |
| 3 | $uri/index.html | 添加 index.html |
| 4 | $uri.html | 添加 .html 后缀 |
| 5 | @other | 命名 location |
# 与 error_page 配合使用
location / {
try_files $uri $uri/ /error.phpc=404 =404;
}递归错误页面
语法:recursive_error_pages on|off; 默认:off
配置块:http、server、location
确定是否允许递归定义 error_page。
内存及磁盘资源分配
临时文件路径
| 配置项 | 语法 | 默认值 | 说明 |
|---|---|---|---|
| 客户端请求体临时文件 | client_body_temp_path path [level1 [level2 [level3]]]; | client_body_temp | 存放客户端请求体临时文件 |
| 代理临时文件 | proxy_temp_path path [level1 [level2 [level3]]]; | proxy_temp | 存放代理响应临时文件 |
| FastCGI 临时文件 | fastcgi_temp_path path [level1 [level2 [level3]]]; | fastcgi_temp | 存放 FastCGI 响应临时文件 |
目录层级结构:
client_body_temp_path /tmp/nginx/client_body 1 2;| 层级 | 说明 | 示例 |
|---|---|---|
| level1 | 一级子目录数量 | 16(0-F) |
| level2 | 二级子目录数量 | 256(0-FF) |
| level3 | 三级子目录数量 | 256(0-FF) |
网络连接设置
连接超时配置
| 配置项 | 语法 | 默认值 | 说明 |
|---|---|---|---|
| Keep-Alive 超时 | keepalive_timeout timeout [header_timeout]; | 75s | 保持连接的超时时间 |
| 客户端请求体超时 | client_body_timeout time; | 60s | 读取请求体的超时 |
| 客户端请求头超时 | client_header_timeout time; | 60s | 读取请求头的超时 |
| 发送响应超时 | send_timeout time; | 60s | 向客户端发送响应的超时 |
http {
keepalive_timeout 65;
client_body_timeout 30;
client_header_timeout 30;
send_timeout 30;
}缓冲区配置
| 配置项 | 语法 | 默认值 | 说明 |
|---|---|---|---|
| 客户端请求体缓冲区 | client_body_buffer_size size; | 8k 或 16k | 请求体缓冲区大小 |
| 客户端请求头缓冲区 | client_header_buffer_size size; | 1k | 请求头缓冲区大小 |
| 大请求头缓冲区数量 | large_client_header_buffers number size; | 4 8k | 大请求头的缓冲区数量和大小 |
| 输出缓冲区数量 | output_buffers number size; | 1 32k | 输出缓冲区数量和大小 |
MIME 类型设置
文件类型映射
语法:include mime.types; 或 types { ... }
include mime.types;
# 或手动定义
types {
text/html html htm shtml;
text/css css;
image/jpeg jpg jpeg;
}默认 MIME 类型
语法:default_type mime-type; 默认:default_type text/plain;
default_type application/octet-stream;对客户端请求的限制
请求体大小限制
| 配置项 | 语法 | 默认值 | 说明 |
|---|---|---|---|
| 请求体最大大小 | client_max_body_size size; | 1m | 允许的请求体最大大小 |
| 请求缓冲区大小 | client_body_buffer_size size; | 8k 或 16k | 请求体缓冲区大小 |
client_max_body_size 10m; # 限制上传文件大小为 10MB请求速率限制
语法:limit_req_zone key zone=name:size rate=rate; 和 limit_req zone=name [burst=number] [nodelay];
http {
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
server {
limit_req zone=one burst=20;
}
}| 参数 | 说明 |
|---|---|
rate | 请求速率,如 10r/s(每秒 10 个) |
burst | 允许突发的请求数量 |
nodelay | 不延迟处理超出 burst 的请求,直接拒绝 |
文件操作优化
Sendfile
语法:sendfile on|off; 默认:sendfile off;
配置块:http、server、location
使用内核的 sendfile 系统调用传输文件,减少数据拷贝。
| 值 | 说明 |
|---|---|
on | 使用 sendfile,性能更好(推荐) |
off | 禁用 sendfile,兼容性更好 |
sendfile on;TCP 选项
| 配置项 | 语法 | 默认值 | 说明 |
|---|---|---|---|
| TCP_NOPUSH | tcp_nopush on/off | off | 数据包填满后发送 |
| TCP_NODELAY | tcp_nodelay on/off | on | 禁用 Nagle 算法 |
sendfile on;
tcp_nopush on;
tcp_nodelay on;Gzip 压缩
| 配置项 | 语法 | 默认值 | 说明 |
|---|---|---|---|
| 开启压缩 | gzip on/off | off | 是否启用 gzip 压缩 |
| 压缩级别 | gzip_comp_level level | 1 | 压缩级别(1-9) |
| 最小压缩文件 | gzip_min_length length | 20 | 最小压缩文件大小 |
| 压缩类型 | gzip_types mime-type... | text/html | 压缩的 MIME 类型 |
gzip on;
gzip_comp_level 6;
gzip_min_length 1000;
gzip_types text/plain text/css application/json application/javascript;URL 重写
语法:rewrite regex replacement [flag];
配置块:server、location、if
# 将旧 URL 重定向到新 URL
rewrite ^/old/(.*)$ /new/$1 permanent;
# 将 .php 去除
rewrite ^/(.*)\.php$ /$1 last;| 标志 | 说明 |
|---|---|
last | 停止当前 rewrite,重新搜索 location |
break | 停止 rewrite,继续处理请求 |
redirect | 返回 302 临时重定向 |
permanent | 返回 301 永久重定向 |
完整配置示例
http {
include mime.types;
default_type application/octet-stream;
# 连接超时
keepalive_timeout 65;
client_body_timeout 30;
client_header_timeout 30;
send_timeout 30;
# 缓冲区
client_body_buffer_size 128k;
client_header_buffer_size 1k;
large_client_header_buffers 4 16k;
# 文件操作优化
sendfile on;
tcp_nopush on;
tcp_nodelay on;
# Gzip 压缩
gzip on;
gzip_comp_level 6;
gzip_min_length 1000;
gzip_types text/plain text/css application/json application/javascript;
# 请求限制
client_max_body_size 10m;
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
# 虚拟主机
server {
listen 80;
server_name example.com;
location /static/ {
root /var/www/static;
expires 30d;
}
location / {
try_files $uri $uri/ @backend;
limit_req zone=one burst=20;
}
location @backend {
proxy_pass http://backend_server;
}
error_page 404 500 502 503 504 /50x.html;
location = /50x.html {
root /var/www/error;
}
}
}常见问题
root 和 alias 的区别
| 特性 | root | alias |
|---|---|---|
| 路径拼接 | root + URI | 替换 location 后的 URI |
| 推荐 | 一般文件服务 | 需要重写 URI 路径时 |
提高文件传输性能
sendfile on;
tcp_nopush on;
tcp_nodelay on;
gzip on;