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;