# 配置
# 配置文件
- Nginx 默认采用
/etc/nginx/nginx.conf
作为主配置文件,还会导入/etc/nginx/conf.d/
目录下的其它配置文件。 - 配置文件的扩展名为 .conf ,采用 Nginx 自定的语法,用 # 声明单行注释。
- 配置文件分为多个层级,最外层称为 main ,其下可以包含 events、http 等区块。
- 每个层级的缩进距离建议为 4 个空格,但也可以不缩进,不影响语法。
- 每条指令大多独占一行,以 ; 结尾。
- 配置文件中,有的指令只能使用一次,有的指令可以重复使用。
- 如果在局部作用域、外部作用域同时使用了某一条指令,则局部作用域里那条指令的优先级更高。
# nginx.conf
/etc/nginx/nginx.conf
的默认内容如下:
user nginx; # 启动 Nginx 主进程的用户名
worker_processes auto; # 启动的 worker 进程数,默认为 1 ,设置成 auto 则会等于 CPU 核数
# worker_shutdown_timeout 60s; # 限制 worker 进程优雅终止的超时时间。默认没有超时时间,可能一直于 shutting down 状态
# daemon off; # 是否以 daemon 方式运行 Nginx 进程,默认为 on
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid; # 将 Nginx 主进程的 PID 记录到该文件中
events {
worker_connections 512; # 每个 worker 进程的最大并发连接数,包括与客户端的连接、与 upsteam 的连接。默认为 512 。该值应该不能超过 ulimit -n 限制
# use epoll; # 处理请求事件的方法,默认会自动选择。在 Linux 上优先采用 epoll ,其次是 poll、select 等
}
http {
include /etc/nginx/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 /var/log/nginx/access.log main;
sendfile on;
# tcp_nopush on;
keepalive_timeout 65;
# gzip on;
include /etc/nginx/conf.d/*.conf;
}
- 用 include 指令可导入指定文件的内容到当前配置。
- Nginx 默认会在 HTTP 响应头中记录服务器信息,例如
server: nginx/1.23
,建议设置server_tokens off;
,隐藏版本号,提高安全性。
# default.conf
/etc/nginx/conf.d/
目录下默认存在一个 default.conf
,配置了 Nginx 的初始 Web 页面,如下:
server {
listen 80; # 该 server 监听的地址(必填)
server_name localhost; # 监听的域名(可选)
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
- http{} 区块中至少要定义一个 server{} ,才能监听 TCP 端口,接收 HTTP 请求。
- server{} 区块中至少要定义一个 location{} ,才能对 HTTP 请求进行路由处理。
# 变量
- Nginx 提供了一些内置变量,用户也可以自定义变量。
- 变量可以通过
$var
的格式取值。- 变量名不区分大小写。
- 如果变量不存在,则报错:
unknown variable
- 内置变量的默认值为 - 。
- 例:
location / { return 200 '$request_uri\n'; }
# set
:为一个变量赋值。如果该变量不存在则自动创建它。
- 可用范围:server
- 语法:
set $variable value;
- 例:
server { listen 80; set $port_type 8x; }
- 注意被赋值的变量名之前要加前缀 $ 。
- 不能给 Nginx 的内置变量赋值,否则会报错:
duplicate variable
- 变量的值可以是数字或字符串类型。
# map
:用于将源变量输入字典取值,并赋值给目标变量。
- 可用范围:http
- 例:
map $server_port $port_type{ # default ''; # 如果字典中没有匹配的 key ,则取默认值 80 8x; # 将源变量与 key 进行字符串匹配 ~ 9\d 9x; # 正则匹配 ~*9\d 9x; # 不区分大小写的正则匹配 }
# 内置变量
关于服务器:
server_addr # 服务器的 IP ,由请求指向的 IP 决定,比如 127.0.0.1 server_name # 服务器的名称,取决于 Nginx 中 server{} 模块配置的 server_name server_port # 服务器监听的端口号 hostname # 服务器的主机名,由服务器所在主机决定 pid # Nginx 当前 worker process 的 PID nginx_version # Nginx 的版本号 upstream_addr upstream_response_time msec # Unix 时间戳格式的服务器时间,比如 1603792024.820 time_iso8601 # ISO 格式的服务器时间,比如 2020-10-28T10:27:14+08:00 time_local # 日志格式的服务器时间,比如 28/Oct/2020:10:27:14 +0800
关于客户端:
remote_addr # 客户端的地址 remote_port # 客户端的端口 remote_user # 客户端的用户名(用于 HTTP Basic Auth) http_referer http_user_agent
关于 HTTP 请求:
request # 请求报文的第一行,比如 GET /static/1.html HTTP/1.1 request_method # 请求的方法名,采用大写,比如 GET request_uri # 请求的原始 URI ,不包括 query string uri # 请求的当前 URI ,取值会因为 rewrite、alias 而改变 args # 请求 URL 中的 Query String is_args # 如果存在 Query String 则取值为 ? (即使格式不正确),否则取值为空 args_XXX # Query String 中指定参数的值,不区分大小写 host # 请求指向的服务器地址,不包括端口号。按优先级取值:请求行中的主机名、请求头中的 Host 字段、处理该请求的 server_name request_filename # 请求 URI 指向的服务器文件,比如 /www/static/1.html document_root # request_filename 文件在服务器上所处的根目录,通常由 root 指令决定 request_length # 请求报文的长度 server_protocol # 请求采用的协议及版本,通常取值为 HTTP/1.0、HTTP/1.1 或 HTTP/2.0 scheme # 请求采用的协议,取值为 http 或 https https # 如果请求采用了 HTTPS 协议则取值为 on ,否则取值为空 http_XXX # headers 中指定参数的值,不区分大小写,要将 - 写作 _ cookie_XXX # cookie 中指定参数的值,不区分大小写 request_time # 请求的处理时长,指从开始接收请求到发完响应报文的耗时。单位 s ,小数点后保留 3 位,即精确到 ms request_body # 请求 body 。只有当 Nginx 执行了 proxy_pass、fastcgi_pass、uwsgi_pass 或 scgi_pass 时才会将请求 body 载入内存,否则该变量取值为空
关于 HTTP 响应:
status # 响应报文的状态码 bytes_sent # 响应报文的大小,单位为 bytes body_bytes_sent # 响应报文 body 的大小
# 日志指令
# access_log
:配置 Nginx 的访问日志,它会记录 Nginx 处理的所有 HTTP 请求。
- 可用范围:http、server、location、limit_except
- 语法:
access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];
- 日志文件所在目录必须存在。
- Nginx 每次写入日志时会打开文件描述符,写完之后就会关闭。
- buffer 的默认大小为 64k 。
- 启用 buffer 时,Nginx 不会立即将日志写入文件,而是先放入 buffer 缓存,直到满足以下任一条件:
- buffer 满了。
- buffer 中保留的日志超过 flush 秒。
- Nginx worker 正在关闭或重新打开日志文件。
- gzip 的默认压缩级别为 1 。取值为 9 时压缩率最高,速度最慢。
- 例:
access_log off; # 取消当前作用域的访问日志
access_log logs/access.log combined gzip=1 flush=5m if=$need_log;
# error_log
:配置 Nginx 的错误日志,它会记录 Nginx 的内部运行信息。
- 可用范围:main ,http ,mail ,stream ,server ,location
- 语法:
error_log path [level];
- 日志级别从复杂到简单依次为:debug, info, notice, warn, error, crit, alert, emerg
# log_format
:定义日志格式。该格式只能被 access_log 命令调用。
- 可用范围:http
- 默认值:
log_format combined '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent"';
- log_format 指令只能定义 access_log 的格式,不能改变 error_log 的格式。
# 流程控制指令
# if
:如果条件为真,则执行括号内的指令。
- 可用范围:server、location
- 例:
if ($uri ~ /www/(\d+)/(.+)) { set $param1 $1; set $param2 $2; return 200 '$param1, $param2\n'; }
- Nginx 不支持 else 子句。
- if 指令虽然比较灵活,但是很多指令不支持在 if 语句块内使用,需要谨慎。
- 条件表达式有多种类型:
- 取值为空字符串
''
或0
则为假,否则为真。 - 用
=
、!=
进行比较运算。 - 用
~
、!~
进行正则匹配,用~*
、!~*
进行不区分大小写的正则匹配。 - 用
-f
、!-f
判断文件是否存在。 - 用
!-d
、!-d
判断目录是否存在。
- 取值为空字符串
# break
:跳过执行 ngx_http_rewrite_module 模块的指令。
- 可用范围:server、location
- 例:
if ($slow) { limit_rate 10k; break; }
- ngx_http_rewrite_module 模块的指令包括 if、break、return、rewrite、set 等
# return
:直接生成一个 HTTP 响应报文,返回给客户端。(不会执行后续指令)
- 可用范围:server、location
- 例:
server{ listen 80; return 404; # 只返回状态码 return 200 OK\n; # 返回状态码和一个字符串(字符串可以不加定界符) return 200 '{"name":"test","id":"001"}'; # 返回状态码和 JSON 格式的字符串 return 302 /index.html; # 返回 302 状态码,并指定重定向的目标 }