# Nginx 基础配置和语法
# 全局变量
Nginx 有一些常用的全局变量,可以在配置的任何位置使用他们。列举一些比较常见的:
变量 | 描述 |
---|---|
HTTP 相关的变量 | |
$host | 请求行中的 Host,如果有 Host 请求头,则用其值替换掉请求行中的主机名,如果请求中没有 Host 行和 Host 请求头,则等于请求匹配的 server 名称(处理请求 server 的 server_name 指令的值),值为小写,不包含端口 |
$uri | 请求中的当前 URI(不同于 URL ,不包括 ? 后面的请求参数,参数位于 $args ),不同于浏览器传递 $request_uri 的值,它可以通过内部重定向,或者使用 index 指令进行修改,不包括协议和主机名,例如 /abc/ef.html |
$document_uri | 当前请求在 root 指令中指定的值,与 $uri 完全相同,历史问题存在 |
$request_uri | 完整的原始请求 URL(包括 URI 和完整的参数),它无法修改,请查看 $uri 更改或重写 URL |
$scheme | 请求模式,http 或 https |
$request | 原始的 url 请求,含有方法与协议版本,例如 GET /?a=1&b=22 HTTP/1.1 |
$request_method | 客户端请求类型,如 GET、POST |
$request_length | 所有请求内容的大小,包括请求行、头部、包体等 |
$request_body | 请求中的包体,这个变量当且仅当使用反向代理,且设定用内存暂存包体时才有效 |
$request_body_file | 临时存放请求包体的文件,如果包体非常小则不会存文件,可以通过 client_body_in_file_only 强制所有包体存入文件,且可决定是否删除 |
$remote_user | 由 HTTP Basic Authentication 协议传入的用户名 |
$args | 请求中的参数,这个变量可以被修改 |
$arg_PARAMETER | GET 请求中变量名 PARAMETER 参数的值,/test?name=abc ,$arg_name 为 abc |
$is_args | 如果请求有参数则为 "?",否则为空字符串"" |
$query_string | 与 $args 相同 |
$content_length | 请求头中标识包体长度的 Content-Length 字段 |
$content_type | 请求头中标识包体类型的 Content-Type 字段 |
$http_HEADER | HTTP 请求头中的内容,HEADER 为 HTTP 请求中的内容转为小写,- 改为 _ (破折号变为下划线),例如 $http_user_agent |
$http_user_agent | 客户端 agent 信息 |
$http_cookie | 客户端 cookie 信息 |
$cookie_COOKIE | 跟 $arg_PARAMETER 类似,获取某个 cookie 值 |
TCP 连接相关的变量 | |
$binary_remote_addr | 客户端地址的整型格式,对于 IPv4 是 4 字节,对于 IPv6 是 16 字节 |
$remote_addr | 客户端的 IP 地址 |
$remote_port | 客户端的端口 |
$connection | 递增的连接序号 |
$connection_requests | 当前连接上执行过的请求数,对 keepalive 连接有意义 |
$proxy_protocol_addr | 若使用了 proxy_protocol 协议则返回协议中的地址(原始用户的地址),否则返回空 |
$proxy_protocol_port | 若使用了 proxy_protocol 协议则返回协议中的端口(原始用户的端口),否则返回空 |
$server_addr | 服务器端地址 |
$server_port | 服务器端端口 |
$server_protocol | 服务器端协议,例如 HTTP/1.1 |
$TCP_INFO | tcp 内核层参数,包括 $tcpinfo_rtt 、$tcpinfo_rttvar 、$tcpinfo_snd_cwnd 、$tcpinfo_rcv_space |
Nginx 处理请求过程中产生的变量 | |
$request_time | 请求处理到现在的耗时,单位为秒,精确到毫秒 |
$server_name | 匹配上请求的 server_name 值 |
$https | 如果开启了 TLS/SSL,则返回 on,否则返回空 |
$request_completion | 若请求处理完则返回 OK,否则返回空 |
$request_id | 以 16 进制输出的请求标识 id,该 id 共含有 16 个字节,是随机生成的 |
$request_filename | 待访问文件的完整路径 |
$document_root | 由 URI 和 root/alias 规则生成的文件夹路径 |
$realpath_root | 将 document_root 中的软链接等换成真实路径 |
$limit_rate | 返回客户端响应时的速度上线,单位为每秒字节数。可以通过 set 指令修改对请求产生效果 |
发送 HTTP 响应时相关的变量 | |
$sent_http_HEADER | HTTP 响应头中的内容,HEADER 为 HTTP 响应中的内容转为小写,- 改为 _ (破折号变为下划线),例如 $sent_http_cache_control 、 sent_http_content_type 等 |
$status | HTTP 响应状态 |
$body_bytes_sent | 传送页面的字节数,即响应中 body 包体的长度 |
$bytes_sent | 全部 http 响应的长度 |
$sent_trailer_名字 | 把响应结尾内容里的值返回 |
Nginx 系统变量 | |
$time_local | 以本地时间标准输出的当前时间 |
$time_iso8601 | 使用 ISO 8601 标准输出的当前时间 |
$nginx_version | 当前运行的 Nginx 版本号 |
$pid | 所属 worker 进程的 id |
$pipe | 使用了管道则返回 p,否则返回 . |
$hostname | 所在服务器的主机名,与 hostname 命令输出一致 |
$msec | 1970 年 1 月 1 日到现在的时间,单位为秒,小数点后精确到毫秒 |
# Nginx 如何设置变量
Nginx 的配置文件使用的是一门微型的编程语言。既然是编程语言,一般也就少不了 “变量” 这种东西,但是在 Nginx 配置中,变量只能存放一种类型的值,那就是字符串。
可以用 set
配置指令动态指定变量的值,Nginx 变量名前面有一个 $
符号,并且所有的 Nginx 变量在 Nginx 配置文件中引用时都必须带上 $
前缀
set $limit_rate 1K; #限制对客户端的响应传输速率。
在引用变量时,需要注意引用的变量名之后紧跟着字符时(比如后跟字母、数以及下划线),就需要使用特别的语法来消除歧义:
server {
listen 80;
server_name test.com;
set $temp hello;
location / {
default_type text/html;
return 200 "$temp world";
}
location /close {
default_type text/html;
return 200 "${hello}world"; # 紧跟字符时的用法
}
}
另外需要注意的是,如果想输出 $
符号本身,可以这样做:
geo $dollar {
default "$";
}
server {
listen 80;
server_name test.com;
location {
set $temp "hello ";
default_type text/html;
return 200 "${temp}world:$dollar";
}
}
上面用到了标准模块 ngx_geo 提供的配置指令 geo 来为变量 ${dollar}
赋予字符串 "$",这样,这里返回的就是 "hello world:$"
# Nginx 变量的实现原理
Nginx 的变量对应的模块可以分为:变量的提供模块和变量的使用模块
- Nginx 启动时,提供变量的模块可以在 preconfiguration 中定义新的变量,包括定义好变量名和解析出变量的方法
- HTTP 头部读取完毕后,使用变量的模块,比如 http 的 access 日志,解析 nginx.conf 时定义变量使用方式,处理请求时,会通过变量名去对应的解析出变量的方法中求得变量值
# map 模块通过映射新变量提供更多的可能性
map 模块可以基于已有变量,使用类似switch {case: ... default ...}
的语法创建新变量,为其他基于变量值实现功能的模块提供更多的可能性。ngx_http_map_module 是默认编译进项目的。
# map 指令
语法 map string $variable {...}
,只能在 http 上下文中使用。
string
已有变量,可以是字符串、一个或者多个变量、变量和字符串的组合$variable
生成的新的变量- case 规则(优先级从高到低)
- 字符串严格匹配
- 使用 hostnames 指令,可以对域名使用前缀
*
泛域名匹配 - 使用 hostnames 指令,可以对域名使用后缀
*
泛域名匹配 ~
和~*
正则表达式匹配,后者忽略大小写
- default 规则
- 没有匹配到任何规则时,使用 default
- 缺失 default 时,返回空字符串给新变量,即新变量为 false
- 其他情况
- 使用 include 语法提升可读性
- 使用 volatile 禁止变量值缓存
map $http_host $name {
hostnames;
default 0;
~map\.x\w+\.org.cn 1;
*.xu.org.cn 2;
map.xu.tech 3;
map.xu.* 4;
}
例如请求头 Host: map.xu.org.cn
泛域名匹配优先于正则匹配,所以 $name
是 2。
# split_client 模块对少量用户指定变量(可以实现 AB 测试)
模块默认编译进 Nginx,基于已有变量(已有变量,可以是字符串、一个或者多个变量、变量和字符串的组合)创建新变量。
过程:
- 对已有变量的值执行 MurmurHash2 算法得到 32 位整型哈希数字,记为 hash
- 32 位无符号整型的最大数字 2^32-1,记为 max
- hash/max 可以得到百分比 percent
- 配置指令中指示了各个百分比构成的范围,如 0-1%,1%-5%等,及范围对应的值
- 当 percent 落在哪个范围里,新变量的值就对应着其后的参数。
case 规则
- xx.xx% 支持小数点后 2 位,所有项的百分比相加不能超过 100%
*
由它匹配剩余的百分比(100%减去以上所有项相加的百分比)
split_clients "${http_testcli}" $variant {
0.51% .one;
20.0% .tow;
* "";
}
# geo 模块根据 IP 地址范围生成新变量
语法 geo [$address] $variable {...}
,根据 IP 地址创建新变量,默认编译进 Nginx。只能在 HTTP 上下文中使用。
- 如果 geo 指令后不输入 $address,那么默认使用 $remote_addr 变量作为 IP 地址
- {} 内的指令匹配:优先最长匹配
- 通过 IP 地址及子网掩码的方式,定义 IP 范围,当 IP 地址在范围内时新变量使用其后的参数值
- default 指定了当以上范围都未匹配上时,新变量的默认值
- proxy 指定新地址,此时 remote_addr 的值为 X-Forwarded-For 头部值中最后一个 IP 地址
- include 优化可读性
- delete 删除指定网络
geo $country {
default ZZ;
#include conf/geo.conf;
proxy 116.62.160.193;
127.0.0.0/24 US;
127.0.0.1/32 RU;
10.1.0.0/16 RU;
192.168.1.0 UK;
}
# Nginx 配置文件的基本结构
拿我们之前编译安装的 Nginx 主配置文件 /usr/local/nginx/conf/nginx.conf
来看,nginx.conf
的结构图大体如下:
main # Nginx 的全局配置,对全局生效
├── events # 配置影响 nginx 服务器或与用户的网络连接
├── http # 配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置,可以嵌套多个 server
│ ├── upstream # 配置后端服务器具体地址,负载均衡配置不可或缺的部分
│ ├── server # 配置虚拟主机的相关参数,如域名、IP、端口等,一个 http 块中可以有多个 server 块
│ ├── server
│ │ ├── location # 配置请求的路由,以及各种页面的处理情况
│ │ ├── location # server 块可以包含多个 location 块,location 指令用于匹配 uri
│ │ └── ...
│ └── ...
└── ...
# Nginx 配置文件的语法规则
Nginx 是由一些模块组成,一般在配置文件中使用一些具体的指令来控制。 指令被分为简单指令(简称指令)和块级指令(简称指令块)。
# 简单指令
简单指令是由名字和参数组成,中间用空格分开,并以分号结尾。
#简单指令
root /data/www;
# 块级指令
块级指令跟简单指令有类似的结构,但是末尾不是分号而是用大括号( {}
)包裹的额外指令集。如果一个块级指令的大括号中有其他指令,则它被叫做一个上下文(比如: events、http、server 和 location)。
在配置文件中,没有放在任何上下文中的指令都处在主上下文中。events
和 http
的指令是放在主上下文中,server
放在 http
中,location
放在 server
中。
#块级指令
http {
server {
listen 80;
server_name doc.chenfangxu.com;
access_log logs/doc.chenfangxu.access.log;
root html;
location ~ \.php$ {
fastcgi_pass 127.0.0.1:1025;
}
}
}
# 语法规则
- 配置文件由指令与指令块构成
- 每条指令以分号(
;
)结尾,指令与参数间以空格符号分隔 - 指令块以大括号(
{}
)将多条指令组织在一起 include
语句允许组合多个配置文件以提升可维护性- 通过
#
符号添加注释,提高可维护性 - 通过
$
符号使用变量 - 部分指令的参数支持正则表达式,例如常用的 location 指令
# location 指令规则
location 指令用于仅匹配 uri,忽略参数,可以使用合法的字符串或者正则表达式
语法:
location [ = | ~ | ~* | ^~ | 空] uri {
……
}
指令后面:
=
:精确匹配,用于不含正则表达式的 uri 前,如果匹配成功,不再进行后续的查找^~
:前缀匹配,用于不含正则表达式的 uri 前,表示如果该符号后面的字符是最佳匹配。采用该规则,不再进行后续的正则查找。跟=
的区别是,不需要 uri 一模一样,只需要开头和 uri 匹配即可。~
:正则匹配,表示用该符号后面的正则 uri 去匹配路径,区分大小写~*
:正则匹配,表示用该符号后面的正则 uri 去匹配路径,不区分大小写。空
:普通匹配(最长字符匹配),匹配以 uri 开头的字符串,只能是普通字符串。例如,location /
是通用匹配,任何请求都会匹配到。另外普通匹配与 location 顺序无关,是按照匹配的长短来确定匹配结果。
# 优先级
location =
> location 完整路径
(还会去匹配正则) > location ^~ 路径
> location ~,~* 正则顺序
> location 部分起始路径
> location /
即:精确匹配 > 最长字符串匹配,完全匹配(还会去匹配正则) > 前缀匹配 > 正则匹配 > 普通匹配(最长字符串匹配,部分匹配) > 通用匹配
# 注意:
- 在所有匹配成功的 uri 中,选取匹配度最长的 uri 字符地址。正则除外,正则匹配是按照先后顺序确定匹配结果
- 正则匹配成功之后停止匹配,普通匹配成功后还会接着匹配正则。举个例子:
# `location 完整路径` 虽然比 `location ^~ 路径` 优先级高,但还是会去匹配正则
# 如果正则匹配成功,采用正则匹配结果。如果没有匹配到 `location 完整路径`,`location ^~ 路径` 就比 `location ~,~* 正则顺序` 优先级高了
location ~ /ab {
rewrite ^ http://baidu.com/s?word=A;
}
location /abc {
rewrite ^ http://baidu.com/s?word=B;
}
location ^~ /ab {
rewrite ^ http://baidu.com/s?word=C;
}
#访问 http://docs.chenfangxu.com/ab 会跳到百度搜索关键词 C
#访问 http://docs.chenfangxu.com/abc 会跳到百度搜索关键词 A
- 如果 uri 包含正则表达式,则必须有
~
或~*
标志,否则正则代码只能作为普通字符使用,例如location = /demo$
,其中的$
并不代表正则模式结束,而是一个实实在在的$
字符,是 url 的一部分。 - 针对
~
和~*
匹配标识符,可以在前面加上!
来取反:!~
:表示正则不匹配,区分大小写,!~*
:表示正则不匹配,不区分大小写
# 根据优先级来模拟 Nginx location 的匹配过程
- Nginx 首先根据 url 检查最长匹配前缀字符串,即会判断
=
、^~
、空
修饰符定义的内容
- 如果匹配到最长匹配前缀字符串(即最长的 uri)
- 如果最长匹配前缀字符串被
=
修饰符匹配,则立即响应 - 如果没有被
=
修饰符匹配,则执行第 2 步判断。
- 如果最长匹配前缀字符串被
- 如果没有匹配到最长匹配前缀字符串
- Nginx 继续检查最长匹配前缀字符串,即判断
^~
、空
修饰符定义的内容
- 如果最长匹配前缀字符串被
^~
修饰符匹配,则立即响应 - 如果被
空
修饰符匹配,则将改匹配保存起来(不管是普通匹配的完全匹配还是部分匹配),并执行第 3 步判断。
- Nginx 找到 nginx.conf 中定义的所有正则匹配(
~
和~*
),并按顺序进行匹配。
- 如果有任何正则表达式匹配成功,则立即响应
- 如果没有任何正则匹配成功,则响应第 2 步中存储的
空
修饰符匹配结果。
# loaction 其他
@
开头的是用于内部跳转的命名 location。- merge_slashes 可以合并 url 中的重复斜杠,除了 base64 编码的格式,其他情况都需要打开
# 典型配置
# 源码编译安装到 /usr/local/nginx
的 Nginx 典型配置
#user nobody; # 定义 Nginx 运行的用户和用户组,默认由 nobody 账号运行,可以不进行设置
worker_processes 1; # Nginx 进程数,一般设置为同 CPU 核数一样
# Nginx 的错误日志存放目录,后面可以跟日志类型
# 全局错误日志定义类型包括:[ debug | info | notice | warn | error | crit ]
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid; # Nginx 服务启动的 pid 存储位置
events {
# 参考事件模型,use [ kqueue | rtsig | epoll | /dev/poll | select | poll ];
# epoll模型是Linux 2.6以上版本内核中的高性能网络I/O模型,如果跑在FreeBSD上面,就用kqueue模型。
#use epoll;
worker_connections 1024; # 每个进程允许最大并发数
}
http { # 配置使用最频繁的部分,代理,缓存,日志定义等绝大多数功能和第三方模块的配置都在这里设置
# include 是个主模块指令,可以将配置文件拆分并引用,减少主配置文件的复杂度
include mime.types; # 文件扩展名与类型映射表
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 logs/access.log main; # Nginx 访问日志存放位置
sendfile on; # 开启高效传输模式
#tcp_nopush on; # 减少网络报文段的数量,防止网络阻塞
#autoindex on; # 开启目录列表访问,适合下载服务器
#keepalive_timeout 0;
keepalive_timeout 65; # 保持连接的时间,也叫超时时间,单位秒,默认为0
#gzip on;
include /usr/local/nginx/conf/conf.d/*.conf; # 加载子配置项
server { # 配置虚拟主机的相关参数,如域名、IP、端口等
listen 80; # 配置监听的端口
server_name localhost; # 配置的域名,可以有多个,用空格隔开
#charset koi8-r; # 默认编码
#access_log logs/host.access.log main; # 定义本虚拟机的访问日志
location / {
root html; # 网站根目录
index index.html index.htm; # 默认首页文件
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html; # 默认50x对应的访问页面
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
# yum 安装的 Nginx 典型配置
user nginx; # 运行用户
worker_processes 1; # Nginx 进程数,一般设置为同 CPU 核数一样
error_log /var/log/nginx/error.log warn; # Nginx 的错误日志存放目录
pid /var/run/nginx.pid; # Nginx 服务启动时的 pid 存放位置
events {
use epoll; # 使用epoll的I/O模型(如果你不知道Nginx该使用哪种轮询方法,会自动选择一个最适合你操作系统的)
worker_connections 1024; # 每个进程允许最大并发数
}
http { # 配置使用最频繁的部分,代理、缓存、日志定义等绝大多数功能和第三方模块的配置都在这里设置
# 设置日志模式
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; # Nginx访问日志存放位置
sendfile on; # 开启高效传输模式
tcp_nopush on; # 减少网络报文段的数量
tcp_nodelay on;
keepalive_timeout 65; # 保持连接的时间,也叫超时时间,单位秒
types_hash_max_size 2048;
include /etc/nginx/mime.types; # 文件扩展名与类型映射表
default_type application/octet-stream; # 默认文件类型
include /etc/nginx/conf.d/*.conf; # 加载子配置项
server {
listen 80; # 配置监听的端口
server_name localhost; # 配置的域名
location / {
root /usr/share/nginx/html; # 网站根目录
index index.html index.htm; # 默认首页文件
deny 172.168.22.11; # 禁止访问的ip地址,可以为all
allow 172.168.33.44; # 允许访问的ip地址,可以为all
}
error_page 500 502 503 504 /50x.html; # 默认50x对应的访问页面
error_page 400 404 error.html; # 同上
}
}
# 配置中常用指令详细说明
# 指令介绍
指令是有 Context 的,不同的指令可以应用的 Context 可能也不同。
- 值指令,主要是存储配置项的值,值指令可以合并,继承规则是向上覆盖,即子配置不存在时,直接使用父配置,子配置存在时,直接覆盖父配置。例如
root
、access_log
、gzip
等指令 - 动作类指令,主要是指定行为,此类指令不可以合并,例如
rewrite
、proxy_pass
等指令,这些指令生效阶段一般是server_rewrite 阶段
、rewrite 阶段
、content 阶段
。
# main 全局配置
worker_processes 1;
定义在配置文件顶级 main 部分,worker 角色的工作进程个数。master 进程是接受并分配请求给 worker 处理。这个数值可以简单设置为 CPU 的核数 grep ^processor /proc/cpuinfo | wc -l
,也可以是 auto 值。如果开启了 ssl 和 gzip,更应该设置成与逻辑 CPU 数量一样甚至为 2 倍,可以减少 I/O 操作。如果 Nginx 服务器还有其它服务,可以考虑适当减少。
worker_cpu_affinity 0001 0010 0100 1000;
定义在 main 部分。在高并发情况下,通过设置 cpu 粘性来降低由于多 CPU 核切换造成的寄存器等现场重建带来的性能损耗。如 worker_cpu_affinity 0001 0010 0100 1000; (四核)。
use epoll;
写在 events 部分。在 Linux 操作系统下,nginx 默认使用 epoll 事件模型,得益于此,nginx 在 Linux 操作系统下效率相当高。同时 Nginx 在 OpenBSD 或 FreeBSD 操作系统上采用类似于 epoll 的高效事件模型 kqueue。在操作系统不支持这些高效模型时才使用 select。
# http 配置
sendfile on;
开启高效传输模式,sendfile 指令指定 nginx 是否调用 sendfile 函数来输出文件,减少用户空间到内核空间的上下文切换。对于普通应用设为 on,如果用来进行下载等应用磁盘 IO 重负载应用,可设置为 off,以平衡磁盘与网络 I/O 处理速度,降低系统的负载。注意:如果图片显示不正常把这个改成 off。
client_max_body_size 10m;
允许客户端请求的最大单文件字节数。如果有上传较大文件,请设置它的限制值。
# server 虚拟主机
http 服务上支持若干虚拟主机。每个虚拟主机对应一个 server 配置项,配置项里面包含该虚拟主机相关的配置。在提供 mail 服务的代理时,也可以建立若干 server,每个 server 通过监听地址或端口来区分。
listen 80;
监听端口和地址,默认 80,小于 1024 的要以 root 启动,可以只指定端口或者指定地址和端口,例如
listen *:80;
、listen 127.0.0.1:80
server_name localhost;
服务器名,可以设置多个,第一个名字将成为主服务器名称(主域名),服务器名称可以使用
*
代替名称的第一部分或者最后一部分;也可以通过正则匹配(加~
前缀),还可以使用正则表达式进行捕获。server { server_name example.com *.example.com www.example.*; }
# server_name 扩展
1、server_name
第一个名字作为主域名可以配合 server_name_in_redirect
,可以让多个子域名有重定向时,重定向到主域名下。
2、 serve_name
可以使用正则表达式的小括号 ()
创建变量,并且可以使用尖括号 ?<>
来命名变量。
# 使用正则,并且创建变量
server {
server_name ~^(www\.)?(.+)$;
location / {
root /sites/$2;
}
}
# 创建命名变量
server {
server_name ~^(www\.)?(?<domain>.+)$;
location / {
root /sites/$domain;
}
}
3、 .example.com
可以匹配到 example.com
*.example.com
4、 _
匹配所有域名
5、 在某个 server 块下的 server_name 使用 ""
匹配没有传递 Host 头部的请求
# 多个 server 块的匹配顺序
- 优先精确匹配,跟 server 块在 nginx.conf 中的顺序无关
- 其次优先匹配
*
在前的泛域名 - 其次优先匹配
*
在后的泛域名 - 其次匹配到正则表达式,匹配顺序是按 nginx.conf 文件中的出现顺序匹配正则表达式域名
- 最后会匹配到 default server,default server 又分为两种情况,第一种是匹配第一个 server 块,另一种情况是如果
listen
指令后面有default
时,所在的 server 块就是 default server。
# localtion
# 访问控制 allow/deny
Nginx 的访问控制模块默认就会安装,而且写法简单,可以分别有多个 allow/deny ,允许或禁止某个 ip 或 ip 段访问,依次满足任何一个规则就停止往下匹配。
location /nginx-status {
allow 192.168.10.100;
allow 172.29.73.0/24;
deny all;
}
我们也常用 httpd-devel 工具的 htpasswd 来为访问的路径设置登录密码:(此处笔者没有验证)
htpasswd -c htpasswd admin
New passwd:
Re-type new password:
Adding password for user admin
htpasswd htpasswd admin //修改admin密码
htpasswd htpasswd sean //多添加一个认证用户
location /nginx-status {
# auth_basic "NginxStatus";
# auth_basic_user_file /usr/local/nginx-1.6/htpasswd;
allow 192.168.10.100;
allow 172.29.73.0/24;
deny all;
}
这样就生成了默认使用 CRYPT 加密的密码文件。打开上面 nginx-status 的两行注释,重启 Nginx 生效。
# 列出目录 autoindex
Nginx 默认是不允许列出整个目录的。如果需要此功能,打开 nginx.conf 文件,在 location、server 或 http 部分加入 autoindex on;
,另外两个参数最好也加进去:
autoindex_exact_size off;
默认为 on,显示出文件的确切大小,单位是 bytes。改为 off 后,显示出文件的大概大小,单位是 KB、MB 或者 GB。
autoindex_localtime on;
默认为 off,显示的文件时间为 GMT 时间。改为 on 后,显示的文件时间为文件的服务器时间。
location /images {
root /var/www/nginx-default/images;
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
}
# Nginx 的 if 判断
if (condition) {
……
}
rewrite 模块提供的,可以用在 server,location 上下文中,如果条件 condition 为真,则执行大括号内的指令;遵循值指令的继承规则
# 括号中的表达式语法
# 普通语法
- 当表达式只是一个变量时,如果值为空或任何以 0 开头的字符串都会当做
false
- 直接比较变量和内容时,使用 = 或 !=
if ($request_method != POST) {
return 405;
}
# 正则语法
~
和!~
判断是否匹配正则表达式,区分大小写~*
和!~*
判断是否匹配正则表达式,不区分大小写
# 如果参数中有 id=1 则 301 到指定域名
if ($args ~ id=1) {
rewrite ^ http://example.com permanent;
}
location = /test.html {
set $name aaa;
# 如果参数中有 name=xxx 则使用该值
if($args ~* name=(\w+?)(&|$)) {
set $name $1;
}
# 301 跳转
rewrite ^ /$name.html permanent;
# /test.html => /aaa.html
# /test.html?name=bbb => /bbb.html
}
# 文件及目录
-f
和!-f
判断是否存在文件-d
和!-d
判断是否存在目录-e
和!-e
判断是否存在文件、目录、软连接-x
和!-x
判断文件是否可执行
if (!-f $request_filename) {
return 400;
}
# if 指令出现问题的原因
- if 指令在 rewrite 阶段执行
- if {} 块中的配置,会在 if 条件为真时,替换当前请求的配置
- if {} 同样向上继承父配置
- 当在 rewrite 阶段顺序执行时,每次 if 为真都会替换当前请求的配置(连续的 if 后面的会覆盖前面的)
- if {} 中的配置,会影响 rewrite 阶段之后的阶段执行
# error_page 配置
error_page 指令的语法是 error_page code... [=[response]] uri;
,可以使用的上下文是 http,server,location,if in location
。
例子:
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
error_page 404 =200 /empty.gif
把状态码 404 替换成 200 返回给客户端error_page 404 = /404.php;
error_page 403 http://example.com/forbidden.html
error_page 404 =301 http://example.com/notfound.html
- 根据 @ 符号进行内部跳转
location / {
error_page 404 = @fallback;
}
location @fallback {
proxy_pass http://backend;
}
# Nginx 中的配置单位
# 时间单位
- ms:毫秒(milliseconds)
- s:秒(seconds)
- m:分钟(minutes)
- h:小时(hours)
- d:天(days)
- w:周(weeks)
- M:月(months,30 days)
- y:年(years,365 days)
expires 3m;
# 空间单位
默认为字节(bytes)
- k/K:kilobytes
- m/M:megabytes
- g/G:gigabytes
client_max_body_size 10m;