背景
本文用于介绍Nginx配置文件的内容,先从整体结构上进行介绍,再分功能对常见配置指令进行说明,最后对location和server块的配置进行介绍。
由于Nginx配置文件内容较多,因此将较为复杂的配置指令单独抽出专题进行介绍,如rewrite、upstream、proxy_pass、root和alias等指令,包括以下文章:
Nginx系列-3 servername优先级和location优先级和常用正则表达式
Nginx系列-4 proxy_pass使用和路径拼接问题
Nginx系列-5 root和alias和index和try_files
Nginx系列-6 rewrite使用介绍
Nginx系列-7 upstream与负载均衡
Nginx系列-8 allow与deny和error_page使用介绍
Nginx系列-9 set和变量和if指令
Nginx系列-10 Nginx配置HTTPS
Nginx系列-11 realIp模块使用
Nginx系列-12 使用Lua脚本进行JWT校验
1.nginx配置结构
一般而言,使用Nginx的核心在于根据具体的业务场景修改nginx配置文件。nginx配置文件入口为nginx.conf, 可以划分为全局块、events块和http块。最核心以及最常修改的区域为http块,而全局块和events块的配置相对固定:
#允许运行nginx服务器的用户和用户组
user ewen ewen;
#worker子进程数量,设置为auto则与CPU核数相等(默认值为1)
worker_processes auto;
#worker 进程的最大打开文件数限制(解决“ too many open files”问题)
worker_rlimit_nofile 655350;
#worker子进程异常终止后的core文件大小上限
worker_rlimit_core 1000M;
#运行错误日志存放路径,日志级别可以设置为info,error等,(默认为logs/error.log)
error_log logs/error.log info;
#pid文件存放路径和名称(默认为logs/nginx.pid)
pid logs/nginx.pid;
events {
# 每个 worker 进程同时打开的最大连接数,决定并发处理能力
worker_connections 1024;
}
http {
#http块...
}
说明:可根据需要对上述配置进行调整,后续内容不再涉及http块以外的配置。
其中http块的层级结构如下所示:
http {
#http全局配置
server{
#server全局配置
location {
#...
}
}
server{
#...
}
}
http块由http全局配置和server块组成,server块由server全局配置和location块组成。
http全局配置用于定义全局的HTTP服务器配置参数,作为全局默认的参数,可以被server或者location块中定义的配置覆盖;server块用于定义虚拟服务器配置,可以定义多个域名,指定监听的端口,以及定义location块;location块定义如何处理特定的URL路径,可以通过return指令直接返回、通过proxy_pass转发、通过rewrite重定向,还可通过http相关指令对请求头/体和响应头/体等进行操作。
2.基础配置
部分配置项只能配置在http块或server块或location块,部分可以在多个模块中进行配置。
2.1 include指令
可以配置在:http块、server块、location块
导入其他配置文件, 并将其他文件内容替换到include指令所在位置;可以将负责的配置分解为较小的、易于管理的文件,有利于后期维护。
include可以使用相对路径,也可以使用绝对路径:
include /usr/local/nginx/conf/custom/my_server.conf
#相对于nginx.conf文件
include ./custom/my_server.conf
include可以使用通配符:
#导入/usr/local/nginx/conf/custom/路径下的全部配置文件
include /usr/local/nginx/conf/custom/*.conf
2.2 MIME配置
固定配置在http块
作用是Nginx 处理不同类型的文件时,可以 通过HTTP头部中的Content-Type字段告知客户端(如浏览器)文件的实际类型。一般http全局块中,默认配置如下所示:
#设置包含的mime类型
include mime.types;
#定义响应的默认mime类型
default_type application/octet-stream;
通过include指定引入了mime.types文件中定义的文件类型和MIME类型的映射关系;并指定了默认mime类型为application/octet-stream。由于mime.types枚举了绝大部分场景下用到的文件类型和MIME类型的映射关系,一般不需要配置。
特殊情况下,如后端返回一个seong类型的文件(如a.seong, test.seong), 需要将这种类型告知浏览器,则需要经过如下配置:
types {
text/seong seong;
}
当nginx将seong类型的文件返回给浏览器时,响应头的Content-Type字段为text/seong,方便浏览器获取文件类型。
**说明:**如果不设置,nginx不认识该类型的文件,则会使用默认的application/octet-stream。
2.3 日志
通过error_log和access_log指令配置nginx日志。
error_log可以配置在全局块、http块、server块和location块(location中优先级最高);
access_log不能配置在全局观,可以配置在http块、server块和location块(location中优先级最高);
error_log:用于记录服务器和请求处理过程中的错误信息,使用方式如下:
#error_log 路径 日志级别
error_log logs/error.log info;
可以指定的日志级别包括: debug、info、notice、warn、error、crit、alert、emerg,默认值是error.
access_log:用于记录访问日志, 搭配log_format使用,使用方式如下:
log_format main '$remote_addr - [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';
#access_log 路径 日志格式
access_log logs/access.log main;
其中,log_format指令用于定义日志格式,可以使用变量,可参考"Nginx系列-set和变量"。案例中涉及的变量对应含义为:
[1] $remote_addr: 客户端IP;
[2] $time_local: 本地时间;
[3] $request: url含参数;
[4] $status: 响应状态码;
[5] $body_bytes_sent: 响应体字节大小;
[6] $http_referer: 访问来源,对应请求头Referer字段;
[7] $http_user_agent: 请求头User-Agent字段;
[8] $http_x_forwarded_for: 请求头中的X-Forwarded-For字段(后文介绍);
使用curl http://localhost:8001/query
访问后日志结果为:
127.0.0.1 - [23/Jul/2024:15:11:45 +0800] "GET /query?name=sy HTTP/1.1" 200 4 "-" "curl/7.29.0" "-"
2.4 压缩相关
可以配置在http、server和location块(location优先级最高)
压缩过程消耗CPU资源,压缩后却可以减少数据传输量,二者需要结合具体的业务场景和部署方式进行权衡。
[1] gzip
控制gzip压缩功能的总开关,on开启压缩,off关闭压缩;默认为off.
# 关闭压缩
gzip off;
[2] gzip_proxied
根据响应头判断是否压缩,取值范围有: off关闭, any任意, expired, no-cache等, 默认值为off.
# 关闭压缩
gzip_proxied off;
#任何类型都压缩
gzip_proxied any;
#如果HTTP响应头中包含 Expires 或 Authorization字段,则启用压缩
gzip_proxied expired auth;
#如果响应头中Cache-Control字段的值为no-cache/no-store/private,则启用压缩
gzip_proxied no-cache no-store private;
#如果HTTP响应头中不包含Last-Modified/ETag字段,则启用压缩
gzip_proxied no_last_modified no_etag;
[3] gzip_comp_level
设置压缩级别,取值范围为1-9,压缩比越高,消耗CPU资源越多,压缩率越高;默认值为6.
# 压缩级别为6
gzip_comp_level 6;
[4] gzip_min_length
压缩的最小数据量,如果响应数据小于这个值,则不进行压缩; 默认值1k.
# 压缩最小数据量为1k
gzip_min_length 1024;
[5] gzip_types
指定哪些MIME类型的响应被压缩;默认值为text/html.
gzip_types text/html;
#通常可以设置多种类型
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
#也可以设置全部MIME类型
gzip_types *;
[6] gzip_vary
配置取值范围为on或off;设置为on可以在响应头中包含 Vary: Accept-Encoding 字段,以便浏览器知道响应已经被 gzip 压缩; 默认值off
gzip_vary off;
2.5 超时相关
超时配置可以划分为两个部分:客户带你与Nginx之间,nginx与(上游)后端服务器之间。
可以配置在http、server和location块(location优先级最高)
2.5.1 客户端与Nginx之间
[1] keepalive_timeout
客户端与Nginx保持长连接的超时时间,默认值为75s;如果在此期间内Nginx没有收到新的请求,则断开连接;
# 单位:秒
keepalive_timeout 75;
[2] send_timeout
Nginx发送消息到客户端,客户端的响应超时时间,默认值为60s;此期间内未收到响应,则断开连接。
说明: http的响应消息一般需要分段发出,这个超时时间对每一段而言,即每段消息在发送给客户端后,至收到客户端的确认消息之间的时间间隔是否超期;
# 单位:秒
send_timeout 60;
[3] client_header_timeout
Nginx等待客户端发送完整请求头的超时时间,默认为60s;超时,则响应408(Request Time Out)错误;
# 单位:秒
client_header_timeout 60;
[4] client_body_timeout
Nginx读取客户端发送的消息体的超时时间,默认为60s;超时,则响应408(Request Time Out)错误.
说明: 不是整个消息体的读取时间,而是接受到的相连消息体-segment之间的gap时间;
# 单位:秒
client_body_timeout 60;
2.5.2 Nginx与后端服务器之间
[5] proxy_connect_timeout
Nginx与后端服务器连接超时时间,默认为60s;
# 单位:秒
proxy_connect_timeout 60;
[6] proxy_read_timeout
Nginx从后端接收影响的超时时间,默认为60s, 超时,则关闭与后端连接,向客户端响应错误消息;
# 单位:秒
proxy_read_timeout 60;
[7] proxy_send_timeout
Nginx将消息发送给后端服务器后,服务器的响应超时时间,默认为60s;超时,则关闭与后端连接,向客户端响应错误消息;
# 单位:秒
proxy_send_timeout 60;
2.6 请求头/响应头相关
add_header可以配置在server块、location块(location优先级最高);
proxy_set_header可以配置在http块、server块、location块(location优先级最高);
proxy_set_header作用于Nginx转发给后端服务器的HTTP请求,而add_header作用于Nginx发送给客户端的的HTTP 响应;即可通过proxy_set_header用于设置请求头,add_header用于设置响应头
设置响应头,添加Content-Length头域:
# 强制返回的响应中携带Content-Length头域
add_header Content-Length $upstream_http_content_length;
设置响应头,添加X-Forwarded-For头域:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
2.7 跨域相关
如"SpringMVC系列-7 @CrossOrigin注解与跨域问题"中介绍的跨域内容:
如果ajax是跨域请求,浏览器收到HTTP请求响应后对响应头进行分析——是否支持跨域:支持-请求正常,否则-抛出异常。响应头包含以下几个部分:
(1) Access-Control-Allow-Origin
指定哪些域可以访问请求的资源, 多个用逗号分开; 取值为"file://"时,表示只允许来自本地文件系统的跨域请求, 而* 表示允许所有源访问。
(2) Access-Control-Allow-Credentials
取值范围有true和false; 表示是否允许客户端使用认证信息(如cookies、HTTP身份验证等)进行跨域请求。即取值为true时,客户端可以携带认证信息,如cookies,以进行身份验证和个性化等操作。
(3) Access-Control-Allow-Methods
取值范围为HTTP的方法类型,如GET和POST;指定允许的HTTP请求方法,多个使用逗号分隔。
(4) Access-Control-Allow-Headers
这个头域用于指定允许客户端访问的响应头, 多个值用逗号分隔;
例如,Access-Control-Expose-Headers: X-Custom-Header, Content-Type表示允许客户端访问X-Custom-Header和Content-Type响应头。
上述4个属性是浏览器判断是否跨域的依据。
注意:当指定多个Access-Control-Allow-Origin时,浏览器会报错。
可通过章节2.6中介绍的add_header修改响应头,按业务要求加入跨域配置,可参考如下配置:
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Credentials true;
add_header Access-Control-Allow-Methods *;
add_header Access-Control-Max-Age 3600;
add_header Access-Control-Allow-Headers $http_access_control_request_headers;
2.Other
用于收集Nginx常用配置,后续本章节内容会动态更新!
sendfile:
sendfile设置为on时,使用系统调用sendfile来传输文件,不需要用户空间参与文件的复制,减少了拷贝次数,从而提高了服务器性能;默认值为on.
sendfile on;
tcp_nopush:
# tcp_nopush设置为on时,等到缓冲区慢或者达到一定的时间阈值才会发送TCP数据包,因此会出现延迟发送;
# off时会立刻发送,但会比较频繁地发送;默认值为off.
tcp_nopush on;
3.server块配置
每个server块可以看成一个虚拟机,有自己的域名, 可以选择监听的端口。
通过server_name定义域名,如下所示:
server {
#...
server_name localhost;
}
可以在一个server块中使用多个server_name,也可以在server_name后定义多个域名(用空格分开);
server {
#...
server_name localhost0;
server_name localhost;
}
server {
#...
server_name localhost1 localhost2;
}
通过listen设置监听的端口,如下所示:
server {
#...
listen 8001;
}
如果需要监听多个端口,需要使用多个listen指令,如下所示:
server {
#...
listen 8001;
listen 8002;
}
说明:多个server中可以监听相同的端口。
至于server_name的匹配和优先级问题,请参考文章:“Nginx系列-3 servername优先级和location优先级和常用正则表达式” https://blog.csdn.net/Sheng_Q/article/details/140570442?spm=1001.2014.3001.5501
4.location块配置
location位于server块中,一个server块中可以定义多个location块,用于处理不同的路径,如下所示:
server {
listen 8001;
server_name localhost;
location /query {
#...query处理逻辑
}
location /ask {
#...ask处理逻辑
}
}
如上所示,location(/query)匹配以http://localhost:8001/query开头有的url, 而location(/ask)匹配以http://localhost:8001/ask开头有的url。
案例如下所示:
#nginx.conf配置文件
events{}
http {
server {
listen 8001;
server_name localhost ;
location /query {
return 200 "query success";
}
location /ask {
return 200 "ask success";
}
}
}
其中,return 200 "query success"
表示给客户端发送响应,状态码为200,消息体为"query success".
测试结果如下:
[root@124 conf]# curl http://localhost:8001/query
query success
[root@124 conf]# curl http://localhost:8001/ask
ask success