目录
1.简述
1.1 nginx的配置指令作用域:
作用域 | 说明 |
---|---|
main | 级别 - 高,一个模块的main 级别的配置对所有的server 和location 都是共享的 |
server | 级别 - 中,一个模块的server 级别的配置对所有的location 都是共享的 |
location | 级别 - 低,一个模块的location 只有自己独立的配置 |
1.2 配置文件路径
路径:nginx-1.14.2/conf/nginx.conf
2.location匹配规则
# |指令| |前缀| |匹配的网站网址| |匹配URI之后要执行的配置段|
location [=|^~|~|~*] /uri/ { ... }
匹配规则 | 说明 |
---|---|
没有前缀 | 普通匹配(遵循最大前缀匹配规则)。 |
= | 精确(严格)匹配。 |
~ | 区分大小写的正则匹配。 |
~* | 不区分大小写的正则匹配。 |
^~ | 匹配 URI 以某个常规字符串开头,^ 为正则表达式中的开头。 |
!~ | 区分大小写不匹配的正则。 |
!~* | 不区分大小写不匹配的正则。 |
/ | 通用匹配,任何请求都会匹配到。 |
由此我们可以根据是否按照正则匹配将 location 的匹配规则划分为两类:
- 普通location: 包括
没有前缀
、=
、^~
、@
四种。其中@
时用作服务内部的一种转发行为,很少用。 - 正则location: 包括
~
、~*
、!~
、!~*
四种。
3.location优先级
具体的匹配顺序生效规则如下:
- 普通 location 与正则 location 之间的匹配:选择出 “普通 location” 的最大前缀匹配结果后,还需要继续搜索正则 location。如果继续搜索的 “正则 location” 也有匹配上的,那么 “正则 location” 覆盖 “普通 location” 的最大前缀匹配。
- 普通 location 之间:最大前缀匹配。
- 正则 location 之间:按照正则 location 在配置文件中的物理顺序(编辑顺序)匹配,并且只要匹配到一条正则 location,就不再考虑后面的。
- 以上 “普通 location” 指的是
没有前缀
和@
,=
和^~
在匹配到结果后就不再需要继续匹配 “正则 location” 了(^ 表示 “非”,~ 表示 “正则”,字符意思是:不要继续匹配正则)。=
和^~
共同点:都可以阻止继续匹配 “正则 location”。=
和^~
不同点:^~
依然遵守 “最大前缀” 匹配规则,然而=
不是 “最大前缀”,而是必须是严格匹配(exact match)。
所有类型location存在时,优先级排序为:
=
匹配 > ^~
匹配(不是用正则,最大前缀匹配) > 正则匹配 > 没有前缀(最大前缀匹配) > 默认(/)
location / {} 和 location = / {} 的区别:
location / {}
遵守普通 location 的最大前缀匹配,由于任何 URI 都必然以/
根开头,所以对于一个 URI,如果有更 specific 的匹配,那自然是选这个更 specific 的,如果没有,/
一定能为这个 URI 点背(至少能匹配到/
)。也就是说,location / {} 有默认配置的意思,其他更 specific 的配置能 orverwrite 这个默认配置(这也是为什么我们总能看到 location / {} 这个配置的原因)。location = / {}
遵守的是 “严格精确匹配 exact match”,也就是只能匹配 http://host:port/ 请求,同时会禁止继续搜索正则 location。因此如果我们只想对 “GET /” 请求配置作用指令,那么我们可以选 location = / {},这样能减少正则 location 的搜索,因此效率比 location / {} 高(注:前提是我们的目的仅仅只想对 “GET /” 起作用)。
4.内置变量
变量 | 说明 |
---|---|
$args | 请求中的参数值 |
$arg_name | 请求中的的参数名,即?后面的arg_name=arg_value形式的arg_name |
$binary_remote_addr | 客户端地址的二进制形式, 固定长度为4个字节 |
$body_bytes_sent | 传输给客户端的字节数,响应头不计算在内 |
$bytes_sent | 传输给客户端的字节数 |
$connection | TCP连接的序列号 |
$connection_requests | TCP连接当前的请求数量 |
$content_length | Content-Length 请求头字段 |
$content_type | Content-Type 请求头字段 |
$cookie_name | cookie名称 |
$document_root | 当前请求的文档根目录或别名 |
$document_uri | 同 $uri |
$host | 优先级如下:HTTP请求行的host>”HOST”请求头字段>符合请求的服务器名 |
$hostname | 主机名 |
$http_name | 匹配任意请求头字段; 变量名中的后半部分“name”可以替换成任意请求头字段,如在配置文件中需要获取http请求头:“Accept-Language”,那么将“-”替换为下划线,大写字母替换为小写,形如:$http_accept_language即可 |
$https | 如果开启了SSL安全模式,值为“on”,否则为空字符串。 |
$is_args | 如果请求中有参数,值为“?”,否则为空字符串。 |
$limit_rate | 用于设置响应的速度限制,详见 limit_rate。 |
$msec | 当前的Unix时间戳 |
$nginx_version | nginx版本 |
$pid | 工作进程的PID |
$pipe | 如果请求来自管道通信,值为“p”,否则为“.” |
$proxy_protocol_addr | 获取代理访问服务器的客户端地址,如果是直接访问,该值为空字符串 |
$query_string | 请求中的参数值,同 $args |
$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” |
$sent_http_name | 可以设置任意http响应头字段; 变量名中的后半部分“name”可以替换成任意响应头字段,如需要设置响应头Content-length,那么将“-”替换为下划线,大写字母替换为小写,形如:$sent_http_content_length 4096即可。 |
$server_addr | 服务器端地址,需要注意的是:为了避免访问linux系统内核,应将ip地址提前设置在配置文件中。 |
$server_name | 服务器名,www.test.info |
$server_port | 服务器端口 |
$server_protocol | 服务器的HTTP版本, 通常为 “HTTP/1.0” 或 “HTTP/1.1” |
$status | HTTP响应代码 |
$tcpinfo_rtt, $tcpinfo_rttvar, $tcpinfo_snd_cwnd, $tcpinfo_rcv_space | 客户端TCP连接的具体信息 |
$time_iso8601 | 服务器时间的ISO 8610格式 |
$time_local | 服务器时间(LOG Format 格式) |
$uri | 请求中的当前URI(不带请求参数,参数位于 a r g s ) ,可以不同于浏览器传递的 args),可以不同于浏览器传递的 args),可以不同于浏览器传递的request_uri的值,它可以通过内部重定向,或者使用index指令进行修改,$uri不包含主机名,如”/foo/bar.html”。 |
5.基础配置
配置 | 说明 |
---|---|
listen | 设置监视端口号,默认80 |
server_name | 设置Nginx服务器名称,默认localhost |
charset | 设置编码格式,一般设置为utf-8 |
location / | 设置拦截所有请求,默认转发为Nginx首页 |
index | 设置首页文件名,默认index.html index.htm |
root | 设置首页所在路径,默认html |
alias | 功能与root相同,区别在于转发后的路径不同。 (root会截断成功匹配到location规则的部分,而alias会拼接匹配到location规则的部分。) |
error_page 500 … | 设置错误页面地址,默认/50x.html |
6.代理配置
代理模式详解:https://www.cnblogs.com/gbq-dog/p/10653054.html
server {
listen 8001;
server_name localhost;
location /iqiyi {
proxy_pass https://www.iqiyi.com/;
}
}
配置 | 说明 |
---|---|
proxy_pass https://www.test.com | 设置需要代理的地址 (末尾带 / 会截断转发,不带/ 会拼接转发) |
proxy_set_header XXX | 设置转发到服务端的请求头信息 |
proxy_hide_header XXX | 设置反向代理时,隐藏服务端头中的哪些信息 |
proxy_pass_request_body on|off | 设置是否发送请求的body信息,默认on |
proxy_pass_request_headers on|off | 设置是否发送请求的头信息,默认on |
proxy_connect_timeout 60s | 设置nginx与服务器建立连接的超时时间为60s,默认60秒 |
proxy_read_timeout 60s | 设置nginx向服务器发起read请求后,等待的超时时间,默认60秒 |
proxy_send_timeout 60s | 设置nginx向服务器发起write请求后,等待的超时时间,默认60秒 |
proxy_http_version 1.0 | 设置HTTP协议的版本,默认 1.0 |
proxy_ignore_client_abort on|off | 设置当客户端请求中断时,nginx是否继续等待服务器返回请求,默认 off |
proxy_headers_hash_bucket_size 64 | 当配置了proxy_hide_header 和proxy_set_header 时,用于设置nginx保存HTTP报文头的hash表的上限 |
proxy_headers_hash_max_size 512 | 设置proxy_headers_hash_bucket_size 的大可用空间 |
server_namse_hash_bucket_size 512 | 设置server_name的hash 表申请空间大小 |
server_names_hash_max_szie 512 | 设置服务器名称hash表的上限大小 |
proxy_buffering on|off | 设置是否启用缓冲区,默认on |
proxy_buffers 8 4k | 设置缓冲区的数量为8,大小为4k,默认情况下,一个缓冲区的大小等于内存页面大小,可能是4k,也可能是8k,取决于平台 |
proxy_buffer_size 4k | 设置缓冲区大小,从代理后端服务器取得的第一部分的响应内容,会放到这里.小的响应header通常位于这部分响应内容里边.默认来说,该缓冲区大小等于指令 proxy_buffers所设置的;但是,你可以把它设置得更小 |
proxy_busy_buffers_size 4k | 设置标注“client-ready”缓冲区的最大尺寸。而客户端可以一次读取来自一个缓冲区的数据,缓冲被放置在队列中,批量发送到客户端。此指令控制允许是在这种状态下的缓冲空间的大小 |
proxy_max_temp_file_size 2048m | 设置可以缓存的服务器文件上限大小为2G |
proxy_temp_file_write_size 32k | 设置当被代理服务器的响应过大时Nginx一次性写入临时文件的数据量 |
proxy_temp_path | 设置当上游服务器的响应过大不能存储到配置的缓冲区域时,Nginx存储临时文件硬盘路径 |
7.高级配置
7.1 try_files
location / {
try_files $uri $uri/ /index.html;
}
当用户请求 http://localhost/example
时,这里的 $uri
就是 /example
。
try_files 会请求/example
。如果请求有响应,就把响应内容返回。
如果请求/example
没有响应。就请求 $uri/
,增加了一个 /
,也就是看请求 /$root/example/
是否有响应。
如果请求/example
还没有响应,就会 fall back 到最后一个地址 /index.php
,发起一个内部 “子请求”,也就是相当于 nginx 发起一个 HTTP 请求到 http://localhost/index.php
。
举个栗子:
loaction / {
try_files $uri @apache
}
loaction @apache{
proxy_pass http://127.0.0.1:88
include aproxy.conf
}
分析:
try_files方法让Nginx尝试访问后面得$uri
链接,并进根据@apache
配置进行内部重定向。
补充:
try_files也可以以错误代码赋值,如try_files /index.php = 404 @apache
,则表示当尝试访问得文件返回404
时,根据@apache
配置项进行重定向。
7.2 proxy_buffers 缓冲区
配置 | 说明 |
---|---|
proxy_buffering on|off | 设置是否启用缓冲区,默认on |
proxy_buffers 8 4k | 设置缓冲区的数量为8,大小为4k,默认情况下,一个缓冲区的大小等于内存页面大小,可能是4k,也可能是8k,取决于平台 |
proxy_buffer_size 4k | 设置缓冲区大小,从代理后端服务器取得的第一部分的响应内容,会放到这里.小的响应header通常位于这部分响应内容里边.默认来说,该缓冲区大小等于指令 proxy_buffers所设置的;但是,你可以把它设置得更小 |
proxy_busy_buffers_size 4k | 设置标注“client-ready”缓冲区的最大尺寸。而客户端可以一次读取来自一个缓冲区的数据,缓冲被放置在队列中,批量发送到客户端。此指令控制允许是在这种状态下的缓冲空间的大小 |
proxy_max_temp_file_size 2048m | 设置可以缓存的服务器文件上限大小为2G |
proxy_temp_file_write_size 32k | 设置当被代理服务器的响应过大时Nginx一次性写入临时文件的数据量 |
proxy_temp_path | 设置当上游服务器的响应过大不能存储到配置的缓冲区域时,Nginx存储临时文件硬盘路径 |
7.3 proxy_set_header
语法 | 默认值 | 配置段 |
---|---|---|
proxy_set_header field value; | proxy_set_header Host $proxy_host; proxy_set_header Connection close; | http, server, location |
$host 代表代理服务器的IP
$proxy_port 代表代理服务器请求后端服务器的端口
1.proxy_set_header Host $host;
保留原请求头信息
2.proxy_set_header Host $proxy_host;
修改请求头信息中的host为被代理端
3.proxy_set_header Host p r o x y h o s t : proxy_host: proxyhost:proxy_port;
修改请求头信息中的host为被代理服务器的IP:代理服务器的端口
4.proxy_set_header X-Real-IP $remote_addr;
代理前,web端这样获取客户端的IP:
request.getRemoteAddr()
代理后,这样只能获得代理服务器的IP。
因此,将前一个服务器的IP放进变量X-Real-IP
中,此变量名可变,若当前服务器为第一台Nginx服务器,则$remote_addr的值为客户端的IP。
web端可以这样获取:
request.getHeader("X-real-ip")
5.proxy_set_header X-Forwarded-For $remote_addr;
将前一个服务器的IP放进变量X-Forwarded-For
中,若当前服务器为第一台Nginx服务器,则$remote_addr的值为客户端的IP。
web端可以这样获取:
request.getHeader("X-Forwarded-For")
如果有两台代理服务器,则获取结果为:第一台nginx的ip
6.proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
将前一个服务器的IP添加进变量X-Forwarded-For
中,若当前服务器为第一台Nginx服务器,则$remote_addr的值为客户端的IP。
web端可以这样获取:
request.getHeader("X-Forwarded-For")
如果有两台代理服务器,则获取结果为:用户的真实ip,第一台nginx的ip
参考:https://www.cnblogs.com/jsonhc/p/7199295.html?utm_source=itdadao&utm_medium=referral
7.4 rewrite模块
参考:https://www.cnblogs.com/beyang/p/7832460.html
8.补充
8.1 u r i 、 uri、 uri、request_uri、$document_uri的区别
符号 | 例子 |
---|---|
$uri | /stat.do |
$request_uri | /stat.do?id=1585378&web_id=1585378 |
$document_uri | /stat.php |
8.2 root、alias的区别
指令 | 配置段 | 处理结果 |
---|---|---|
root | http、server、location、if | root路径+location路径 |
alias | location | alias路径 |
8.3 last、break的区别
(1)last 和 break 当出现在location 之外时,两者的作用是一致的没有任何差异
(2)last 和 break 当出现在location 内部时:
- last 使用了last 指令,rewrite 后会跳出location 作用域,重新开始再走一次刚才的行为
- break 使用了break 指令,rewrite后不会跳出location 作用域,它的生命也在这个location中终结
8.4 permanent、redirect的区别
- rewrite … permanent 永久性重定向,请求日志中的状态码为301
- rewrite … redirect 临时重定向,请求日志中的状态码为302
参考地址:
[1] Nginx Proxy:https://www.jianshu.com/p/eb586e957c9c
[2] Nginx代理的几种模式:https://www.cnblogs.com/gbq-dog/p/10653054.html
[3] Nginx 缓冲区设置 proxy_buffers相关配置:https://blog.csdn.net/benpaodelulu_guajian/article/details/79198084
[4] nginx优化缓冲区缓存:https://www.cnblogs.com/bethal/p/5606062.html
[5] nginx一篇全搞定:https://www.cnblogs.com/sunshinea121/p/10767344.html
[6] Nginx rewrite模块深入浅出详解:https://www.cnblogs.com/beyang/p/7832460.html
[7] Nginx之location匹配规则:https://www.cnblogs.com/gaoyanbing/p/16915446.html