Nginx 是一款高性能的 HTTP 服务器和反向代理服务器,广泛用于 Web 服务架构中。它的配置文件 nginx.conf 是其核心配置文件,控制着 Nginx 的运行行为、模块加载方式以及站点的路由规则。本文将深入解析 nginx.conf 的结构与常用指令,帮助你全面掌握 Nginx 的配置方法。
一、语法介绍
指令
Nginx 配置文件由一系列指令组成,每个指令以分号 ; 结尾。
指令可以单独成行,也可以一行包含多个指令。
块
大部分指令可以包含在块中,块用 {} 括起来。
块可以包含其他指令或者其他块。
注释
使用 # 符号表示注释,注释可以出现在行的任何位置。
上下文
Nginx 的配置指令可以根据上下文来决定其作用范围。
常见的上下文有 http、server、location 等。
变量
Nginx 支持内置变量和自定义变量。
内置变量表示请求的相关信息,例如 、args 等。
自定义变量通过 set 指令定义,例如 set $my_var value。
通配符
Nginx 支持通配符 *、? 和 ~ 等来匹配 URL。
重定向和重写
rewrite 指令用于重写 URL,可以实现 URL 的修改和重定向。
return 指令用于直接返回指定的 HTTP 状态码和响应内容。
变量和指令的嵌套
Nginx 允许在指令中使用变量,也允许在变量中使用其他变量。
include 指令
include 指令用于在配置文件中包含其他文件的内容。
日志配置
Nginx 允许配置访问日志和错误日志,可以通过 access_log 和 error_log 指令来配置。
二、常用变量参数
# 常用的
$host #请求信息中的Host,如果请求中没有Host行,则等于设置的服务器名
$request_method #客户端的请求类型。如GET、POST
$remote_addr #客户端中的IP地址
$remote_port #客户端端口
$args #请求中的参数
$content_length #请求中的Content-length字段
$http_user_agent #客户端agent信息
$http_cookie #客户端cookie
$server_protovol #请求协议,如HTTP/1.0、HTTP/1.1
$server_addr #服务器地址
$server_name #服务器名称
$server_port #服务器端口
# 其他的
$args #请求中的参数值
$query_string #同 $args
$arg_NAME #GET请求中NAME的值
$is_args #如果请求中有参数,值为"?",否则为空字符串
$uri #请求中的当前URI(不带请求参数,参数位于$args),可以不同于浏览器传递的$request_uri的值,它可以通过内部重定向,或者使用index指令进行修改,$uri不包含主机名,如"/foo/bar.html"。
$document_uri #同 $uri
$document_root #当前请求的文档根目录或别名
$host #优先级:HTTP请求行的主机名>"HOST"请求头字段>符合请求的服务器名.请求中的主机头字段,如果请求中的主机头不可用,则为服务器处理请求的服务器名称
$hostname #主机名
$https #如果开启了SSL安全模式,值为"on",否则为空字符串。
$binary_remote_addr #客户端地址的二进制形式,固定长度为4个字节
$body_bytes_sent #传输给客户端的字节数,响应头不计算在内;这个变量和Apache的mod_log_config模块中的"%B"参数保持兼容
$bytes_sent #传输给客户端的字节数
$connection #TCP连接的序列号
$connection_requests #TCP连接当前的请求数量
$content_length #"Content-Length" 请求头字段
$content_type #"Content-Type" 请求头字段
$cookie_name #cookie名称
$limit_rate #用于设置响应的速度限制
$msec #当前的Unix时间戳
$nginx_version #nginx版本
$pid #工作进程的PID
$pipe #如果请求来自管道通信,值为"p",否则为"."
$proxy_protocol_addr #获取代理访问服务器的客户端地址,如果是直接访问,该值为空字符串
$realpath_root #当前请求的文档根目录或别名的真实路径,会将所有符号连接转换为真实路径
$remote_addr #客户端地址
$remote_port #客户端端口
$remote_user #用于HTTP基础认证服务的用户名
$request #代表客户端的请求地址
$request_body #客户端的请求主体:此变量可在location中使用,将请求主体通过proxy_pass,fastcgi_pass,uwsgi_pass和scgi_pass传递给下一级的代理服务器
$request_body_file #将客户端请求主体保存在临时文件中。文件处理结束后,此文件需删除。如果需要之一开启此功能,需要设置client_body_in_file_only。如果将次文件传 递给后端的代理服务器,需要禁用request body,即设置proxy_pass_request_body off,fastcgi_pass_request_body off,uwsgi_pass_request_body off,or scgi_pass_request_body off
$request_completion #如果请求成功,值为"OK",如果请求未完成或者请求不是一个范围请求的最后一部分,则为空
$request_filename #当前连接请求的文件路径,由root或alias指令与URI请求生成
$request_length #请求的长度 (包括请求的地址,http请求头和请求主体)
$request_method #HTTP请求方法,通常为"GET"或"POST"
$request_time #处理客户端请求使用的时间,单位为秒,精度毫秒; 从读入客户端的第一个字节开始,直到把最后一个字符发送给客户端后进行日志写入为止。
$request_uri #这个变量等于包含一些客户端请求参数的原始URI,它无法修改,请查看$uri更改或重写URI,不包含主机名,例如:"/cnphp/test.php?arg=freemouse"
$scheme #请求使用的Web协议,"http" 或 "https"
$server_addr #服务器端地址,需要注意的是:为了避免访问linux系统内核,应将ip地址提前设置在配置文件中
$server_name #服务器名
$server_port #服务器端口
$server_protocol #服务器的HTTP版本,通常为 "HTTP/1.0" 或 "HTTP/1.1"
$status #HTTP响应代码
$time_iso8601 #服务器时间的ISO 8610格式
$time_local #服务器时间(LOG Format 格式)
$cookie_NAME #客户端请求Header头中的cookie变量,前缀"$cookie_"加上cookie名称的变量,该变量的值即为cookie名称的值
$http_NAME #匹配任意请求头字段;变量名中的后半部分NAME可以替换成任意请求头字段,如在配置文件中需要获取http请求头:"Accept-Language",$http_accept_language即可
$http_cookie
$http_host #请求地址,即浏览器中你输入的地址(IP或域名)
$http_referer #url跳转来源,用来记录从那个页面链接访问过来的
$http_user_agent #用户终端浏览器等信息
$http_x_forwarded_for
$sent_http_NAME #可以设置任意http响应头字段;变量名中的后半部分NAME可以替换成任意响应头字段,如需要设置响应头Content-length,$sent_http_content_length即可
$sent_http_cache_control
$sent_http_connection
$sent_http_content_type
$sent_http_keep_alive
$sent_http_last_modified
$sent_http_location
$sent_http_transfer_encoding
三、配置文件位置
默认情况下,Nginx 的主配置文件位于:/etc/nginx/nginx.conf,此外,Nginx 支持通过 include 指令引入其他配置文件,例如站点配置通常放在 /etc/nginx/conf.d/ 或 /etc/nginx/sites-available/ 目录下。
四、配置文件结构
nginx.conf 的结构采用块级嵌套语法,主要分为以下几个层级:
main { # 全局设置
events { # 网络连接相关配置
...
}
http { # HTTP 协议相关配置
upstream myapp {
...
}
server { # 虚拟主机配置(站点)
location / {
...
}
}
server {
# 第二个虚拟主机配置
}
}
}
main 块(全局配置)
作用于整个 Nginx 进程,包括进程数、用户权限、日志路径等。
user nginx; # 指定运行 Nginx 的用户
worker_processes auto; # 工作进程数,一般设为 CPU 核心数或 auto
error_log /var/log/nginx/error.log notice; # 错误日志路径及级别
pid /var/run/nginx.pid; # PID 文件路径
events 块(事件处理模型)
控制 Nginx 的网络连接机制,如连接数、多路复用模型等。
events {
worker_connections 1024; # 每个 worker 进程最大连接数
use epoll; # 使用 epoll 多路复用(Linux 推荐)
multi_accept on; # 启用一次接收多个新连接
}
说明:
worker_connections 控制单个 worker 可以同时处理的最大连接数。
use 指定使用的 I/O 模型,常见值有 epoll(Linux)、kqueue(BSD)等。
multi_accept 提升高并发场景下的性能。
http 块(HTTP 服务配置)
这是最复杂的部分,包含 MIME 类型定义、日志格式、虚拟主机(server)配置、负载均衡(upstream)等。
http {
include /etc/nginx/mime.types; # 包含 MIME 类型定义
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 /var/log/nginx/access.log main;
sendfile on; # 开启高效文件传输模式
keepalive_timeout 65; # 长连接超时时间
gzip on; # 启用 GZIP 压缩
gzip_types text/plain application/json text/css application/javascript;
upstream backend {
least_conn;
server 127.0.0.1:8080 weight=3;
server 127.0.0.1:8081;
server 127.0.0.1:8082 backup;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
}
五、关键配置项详解
server
每个 server 表示一个独立的网站(虚拟主机),可以监听不同的端口和域名。
server {
# 配置指令
}
listen
listen 是 Nginx 配置中用于指定服务器监听的 IP 地址和端口的指令。它的作用是告诉 Nginx 在哪个地址和端口上监听传入的连接。
# ----------------语法
server {
listen [地址]:端口 [参数];
}
# -----------------例子
# 监听所有地址(IPv4 和 IPv6)的 80 端口
listen 80;
# 只监听 IPv4 地址的 443 端口,并启用 SSL:
listen 443 ssl;
# 同时监听 IPv4 和 IPv6 地址的 8080 端口
listen [::]:8080;
listen 8080;
参数:
地址:可选参数,用于指定监听的 IP 地址。如果不指定,则默认监听所有地址(即 0.0.0.0)。
端口:必选参数,用于指定监听的端口号。
参数:可选参数,用于指定监听的额外选项,例如 SSL、HTTP2 等。
server_name
server_name 是 Nginx 配置中用于指定虚拟主机的域名或者 IP 地址的指令。它的作用是告诉 Nginx 哪些域名或 IP 地址对应于当前的虚拟主机配置。
# --------------------语法
server {
server_name 域名1 [域名2 ...];
}
# --------------------例子
# 指定单个域名
server_name example.com;
# 指定多个域名
server_name example.com www.example.com;
# 使用通配符
server_name *.example.com;
# 使用 IP 地址
server_name 192.168.1.1;
参数:
域名:可以是完整的域名,也可以是通配符或者 IP 地址。可以使用空格分隔多个域名。
通配符:* 表示匹配任意字符,例如 *.example.com 可以匹配 www.example.com、sub.example.com 等。
IP 地址:可以是具体的 IPv4 或 IPv6 地址,例如 192.168.1.1、[2001:0db8::1]。
location
在 Nginx 配置中,location 指令用于定义请求的匹配规则和处理逻辑,它允许你根据请求的 URL 路径对请求进行分类,并在不同的路径下应用不同的配置。
语法:
location [修饰符] 匹配规则 {
# 配置指令
}
修饰符:
=:精确匹配,只有当请求的 URL 完全等于指定的路径时才会匹配。
~:正则表达式匹配,区分大小写。
~*:正则表达式匹配,不区分大小写。
^~:普通字符匹配,优先于正则匹配。
/ :通用匹配, 如果没有其它匹配,任何请求都会匹配到。
匹配规则:
普通字符串:可以是具体的 URL 路径,例如 /images/。
正则表达式:使用 ~ 或 ~* 修饰符定义,例如 ~ ^/images/.+.(jpg|png)$。
特殊字符:例如 / 表示匹配所有请求,~ .php$ 表示匹配所有以 .php 结尾的请求。
匹配规则优先级:
精确匹配(=)优先于其他匹配规则。
普通字符匹配(^~)优先于正则表达式匹配(~ 和 ~*)。
正则表达式匹配按照定义的顺序进行匹配,优先匹配在前面的规则。
“
location 块可以嵌套,允许在更细粒度的路径上定义更具体的配置。
域名匹配的四种写法:
精确匹配:server_name www.mingongge.com ;
左侧通配:server_name *.mingongge.com ;
右侧统配:server_name www.mingongge.* ;
正则匹配:server_name ~^www.mingongge.*$ ;
“
匹配优先级:精确匹配 > 左侧通配符匹配 > 右侧通配符匹配 > 正则表达式匹配
proxy_pass
proxy_pass 指令用于将请求转发给另一个服务器处理,并将该服务器的响应返回给客户端。它通常用于配置 Nginx 作为反向代理服务器,将请求转发给后端的应用服务器或者其他 Web 服务器。
# 语法:
proxy_pass URL;
# 参数:
# URL:必选参数,用于指定后端服务器的地址。可以是 IP 地址、主机名、或者带有协议和端口的完整 URL。
# 例子:
location /proxy/ {
proxy_pass http://127.0.0.1; #代理到URL:http://127.0.0.1/proxy/test.html
proxy_pass http://127.0.0.1/; #代理到URL:http://127.0.0.1/test.html
proxy_pass http://127.0.0.1/aaa; #代理到URL:http://127.0.0.1/aaatest.html
proxy_pass http://127.0.0.1/aaa/; #代理到URL:http://127.0.0.1/aaa/test.html
}
# proxy_pass 指令通常与其他配置指令一起使用
location / {
proxy_pass http://172.17.106.235:18000;
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;
}
root
location中root指定的只是相对路径,需要和路径结合起来映射地址,比如
# 这里的root需要和路径结合使用,即是映射的文件位置为 /usr/html/static
# 例如,对于请求 /static/a.css ,那么就会找到 /usr/html/static/a.css
location ^~/static/ {
root /usr/html/;
index index.html
}
location /web {
root /usr/local/;
index index.html index.htm;
}
“
注意:server下也有root,server是全局的,location是局部的,location会覆盖server的
alias
alias 指令用于在 Nginx 的 server 块中创建一个与请求 URL 不同的文件路径映射。它允许你将请求的 URL 路径替换为指定的别名,并指定一个实际的文件系统路径,alias指定的是绝对路径,不会和location中的路径结合使用,而是直接使用地址映射到文件。
# 在这个示例中,location /images/ 定义了一个 alias,
# 它将 URI 中的 /images/ 映射到文件系统中的 /var/www/images/。
# 例如,对于请求 /images/photo.jpg,Nginx 将查找文件 /var/www/images/photo.jpg。
server {
listen 80;
server_name example.com;
location /images/ {
alias /var/www/images/;
index index.html;
}
}
# 不会路径结合映射地址,那么这里就会直接映射到/usr/html/文件夹下的文件
location ^~/static/ {
alias /usr/html/;
index index.html
}
# 后面不加/会把location的去掉
location /bb {
alias /usr/local/web;
index index.html index.htm;
}
# 后面加了/也会把location的拼接上 如:/data/pages
location /pages/ {
alias /data;
}
try_files
try_files 指令是 Nginx 配置中用于指定文件检查顺序的指令。它用于配置 Nginx 在处理请求时尝试查找文件的顺序,如果文件存在则将其返回给客户端,否则执行指定的操作。
try_files 文件路径1 [文件路径2 ...] 请求处理动作;
参数:
文件路径:必选参数,用于指定要尝试查找的文件路径。可以指定多个文件路径,Nginx 将按照指定的顺序依次尝试查找这些文件。
请求处理动作:必选参数,用于指定当文件不存在时的请求处理动作,可以是以下几种值之一:
uri:将请求重定向到指定的 URI。
return code:返回指定的 HTTP 状态码。
@name:将请求转发到指定的命名位置。
例子:
location / {
try_files $uri $uri/ /index.php?$query_string;
}
在这个例子中,当客户端请求的 URL 匹配 / 路径时,Nginx 将会按照以下顺序尝试查找文件:
首先尝试查找请求的 URI 对应的文件(例如 /path/to/file)。
如果找不到对应的文件,则尝试查找以请求的 URI 结尾的目录(例如 /path/to/file/)。
如果仍然找不到对应的文件,则将请求重定向到 /index.php 并附带原始的查询参数。
index
在 Nginx 中,index 指令用于指定默认的索引文件,当客户端请求的 URL 是一个目录时,Nginx 将会尝试在该目录下寻找指定的索引文件,并将其返回给客户端。
index 文件名 [文件名 ...];
# 例子:
index index.html index.htm;
“
注意:
如果没有明确指定 index 指令,默认的索引文件是 index.html。
如果请求的目录下没有任何指定的索引文件,或者没有权限访问这些文件,则 Nginx 将会返回一个 403 Forbidden 或者 404 Not Found 错误。
server下也有index,server是全局的,location是局部的,location会覆盖server的
autoindex
autoindex 指令是 Nginx 配置中用于开启或关闭目录列表显示的指令。当客户端请求的 URL 是一个目录时,如果开启了 autoindex,Nginx 将会自动列出该目录下的文件和子目录,并生成一个目录列表页面返回给客户端;如果关闭了 autoindex,Nginx 将会返回一个 403 Forbidden 或者 404 Not Found 错误。
autoindex on | off;
# 例子
location /files/ {
autoindex on;
}
# 以通过在 autoindex 指令后面加上额外的参数来定制目录列表显示的样式,例如 autoindex on html; 将会以 HTML 格式显示目录列表。
location /files/ {
autoindex on html;
}
error_page
定义错误页面处理逻辑
error_page 404 /404.html;
error_page 500 502 /50x.html;
access_log 和 error_log
定义访问日志和错误日志路径
error_log /var/log/nginx/error.log;
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 /var/log/nginx/access.log main;