一. 整体结构

nginx的配置位于​​nginx​​​安装目录的​​config​​​目录下,​​nginx​​​下除了​​nginx.conf​​​主配置文件之外,还有一些​​cgi​​(通用网关接口协议程序的配置),相关信息阅读这片文件:

nginx入门指南之配置项详解(三)_配置文件


针对​​nginx​​的配置文件拥有以下几个部分:

  • 全局块:配置影响​​nginx​​全局的指令。一般有运行nginx服务的用户组,​​nginx​​进程的​​pid​​存放路径,日志存放路径,允许生成的​​worker​​进程的数量等等;
  • ​events​​​块:配置影响​​nginx​​服务器或者用户的网路连接。包括每个进程的最大连接数、使用哪种事件驱动模型处理连接请求、是否允许同时接受多个网络连接或者网络连接序列化等等;
  • ​http​​​块:可以嵌套多个​​server​​,配置代理、缓冲和日志定义等功能和第三方模块配置;
  • ​server​​​块:配置虚拟主机的相关参数,一个​​http​​可以有多个​​server​​;
  • ​location​​块:配置请求路由和页面处理

结构如图:

nginx入门指南之配置项详解(三)_子进程_02

二. 配置模板

可以在官网查看所有的指令:​​https://nginx.org/en/docs/dirindex.html​​。

nginx入门指南之配置项详解(三)_nginx_03


接着看下一个模板配置文件:

# 全局部分
user nginx;
group nginx;
worker_process auto;
......
events {
# events 块
worker_connections 768;
......
}

http {
# http 块
include mime.types;
default_type application/octet-stream;
......

server {
# server 块
}

server {
# server 块
}

......
}

这里需要注意一下,如果​​server​​​比较多的话,我们一般不会把​​server​​​放到​​nginx.conf​​这个主配置文件中:

http {
# http 块
include mime.types;
default_type application/octet-stream;

......

include /etc/nginx/conf.d/*.conf; # 引入server
}

这样就可以将​​conf.d​​​目录下的所有​​server​​​的配置文件加载到主配置文件中!主配置文件​​http​​​中就不需要配置​​server​​​了,这里面的​​server.conf​​文件写法如下:

server {
listen 8080;
......

location /api {
......
}
}

二. 全局配置

全局配置是只指在第一部分介绍的main部分的配置,这些配置是全局生效的,下面介绍一个常用的全局配置项:

  • ​user​​​:运行​​nginx​​的​​worker​​子进程的用户和用户组。
  • ​pid​​​:存放​​master​​主进程的PID文件路径。
  • ​lock_file​​​:负载均衡互斥锁文件存放路径。这个配置需要打开​​accept_mutex​​配置。
  • ​error_log​​:存放日志文件,支持设置日志登录,默认是error登录,支持的等级有:debug、info、notice、 warn、error、crit、 alert、 或emerg。
  • ​worker_rlimit_nofile​​​: ​​worker​​子进程可以打开的最大文件句柄。
  • ​worker_rlimit_core​​:存放worker子进程异常终止后的core文件,用于记录分析问题。配置这个项还需要注意配置worker_directory的配置,这个是core文件的存放路径,nginx需要有读写权限。
  • ​worker_processes​​:启动nginx的worker子进程的数量,默认是1,推荐设置为auto。
  • ​worker_cpu_affinity​​:每个worker子进程于物理CPU核心绑定,这样可以避免同一个worker子进程在不同CPU核心上切换,导致缓冲失效,降低性能,但需要注意并不是真正避免切换。
  • ​worker_priority​​:设置worker子进程优先级,这个值越小越优先,值范围为-20 到 +19;通常设置为负值,优先调用。
  • ​worker_shutdown_timeout​​:指定worker子进程优雅退出的超时时间。
  • ​timer_resolution​​:worker子进程内部使用的计时器精度,调整时间间隔越大,系统调用越小,有利于性能提升,反正性能下降。
  • ​daemon​​:设置nginx的运行方式,前台off(调试)还是后台on(生产)

这里在说一下​​worker_cpu_affinity​​这个指令是如何和CPU绑定的:

  • 两核CPU: worker_cpu_affinity 01 10;
  • 四核CPU:worker_cpu_affinity 0001 0010 0100 1000;
  • 以此类推

三. Events核心参数

核心的配置参数:

  • ​use​​​:nginx使用何种事件驱动模型,此配置和​​Linux​​操作系统有关,​​linux​​基本上都是使用的​​epoll​​这个模型,这个配置可以不指定,​​nginx​​会自己选择。
  • ​worker_connections​​​:​​worker​​子进程能够处理的最大并发连接数,默认是1024,这里可以根据​​worker​​子进程数配置(65535/​​worker_processes​​)或者直接设置为65535。
  • ​accept_mutex​​:是否打开负载均衡互斥锁,默认是关闭的off,推荐打开on
  • ​accept_mutex_delay​​​:新连接分配给​​worker​​子进程的超时时间,这个配置依托于​​accept_mutex​​配置,默认500ms,推荐配置为200ms
  • ​muti_accept​​​:​​worker​​子进程可以接收的新连接数, 默认是一个​​worker​​子进程只能处理一个请求,设置​​on​​,这时​​worker​​子进程就可以接受多个请求。

四. http核心配置

http块是nginx服务器配置中的重要部分,代理、缓存和日志定义等绝大多数的功能和第三方模块的配置都可以放在这个模块中。这里的很多配置也可以在​​server​​​和​​location​​中配置。

这里介绍http全局配置项:

  • ​include​​:用于包含其他的配置文件
  • ​default_type​​:配置默认类型,如果不加此指令,默认值为text/plain。还可以在http块、server块或者location块中进行配置。
  • ​log_format​​:用于定义日志格式,此指令只能在http块中进行配置
  • ​sendfile​​:开启关闭sendfile方式传输文件,可以在http块、server块或者location块中进行配置
  • ​sendfile_max_chunk​​:设置sendfile最大数据量,此指令可以在http块、server块或location块中配置
  • ​keepalive_timeout​​:配置连接超时时间,此指令可以在http块、server块或location块中配置
  • ​keepalive_requests​​:配置单连接请求数上限,指令可以在http块、server块或location块中配置

其他的一些关于模块的配置,下一篇文章在介绍!

五. server核心配置

5.1. server_name配置

这个块中的核心配置​​server_name​​​的配置。​​server_name​​有多种配置方法,下面列举示例:

  • 第一种:精确的域名,如:​​server_name www.baidu.com;​
  • 第二种:通配符匹配,如​​server_name *.baidu.com;​​ 和 ​​server_name www.baidu.*;​
  • 第三种:正则表达式匹配(最前面是一个波浪号),如:​​~^www\d+\.baidu\.com$​​表示可以匹配以​​www​​开头,后跟一个到多个数字,然后以​​.baidu.com​​结尾的域名

需要注意​​server_name​​​后面的配置参数支持多种,如:​​server_name www.baidu.com *.baidu.com;​

另外​​server_name​​还需要注意一下这几种配置:

  • ​server_name .baidu.com;​​​相当于​​server_name *.baidu.com baidu.com;​
  • ​_​​__​​ 表示无效域名,可以匹配任意域名,优先最低,常用来设置默认的​​server​​,即当一个请求的域名没有命中其他规则时,会采用默认​​server​​的配置。

server_name优先级:精确配置 > 左侧通配符 > 右侧通配符 > 正则表达式匹配 > 默认配置(default_server)。

5.2. default_server配置

​default_server​​​可以定义默认的 ​​server​​​ 去处理一些没有匹配到 ​​server_name​​​ 的请求,如果没有显式定义,则会选取第一个定义的 ​​server​​​ 作为 ​​default_server​​。

这是捕获未做绑定的域名访问或直接​​IP​​​访问,做重定向到 ​​403​​ 页面等处理。

示例一:没有显式声明 ​​default_server​​​ ,那么第一个 ​​server​​​会被隐式的设为 ​​default_server​

http {
# 第一个作为default server
server {
listen 80;
server_name _;
return 403; # 返回403
}

server {
listen 80;
server_name www.test.com;
...
}
}

示例二:显示的定义​​default_server​

http {
# 将当前server定义为default_server
server {
listen 80 default_server;
server_name _;
return 403; # 返回403
}

server {
listen 80;
server_name www.test.com;
...
}
}

配置nginx禁止ip访问 :这样可以防止别人恶意解析ip。

配置方法一:返回444,403,501等错误

http {
......
server {
listen 80 default_server;
server_name _;
return 444;
}
}

配置方法二:跳到主页

http {
......
server {
listen 80 default_server;
server_name _;
rewrite ^(.*) http://www.test.com permanent;
}
}

5.3. root和alias配置

​root​​​和​​alias​​​都可以后面跟路径参数,作为​​URI​​​到磁盘文件的映射,但是需要注意alias只能使用在​​location​​​中,但是​​root​​​可以在​​http​​​、​​server​​​、​​location​​​和​​if​​中使用。

这个最打的区别在于​​URI​​​路径,​​root​​​会将定义的路径和​​URI​​​叠加;​​alias​​则只取定义路径。

示例一:

http {
server {
location /img {
root /tmp/images;
}
}
}

此时如果访问:www.test.com/img/logo.png,对应的磁盘路径是:/tmp/images/img/logo.png

示例二:

http {
server {
location /img {
alias/tmp/images;
}
}
}

此时如果访问:www.test.com/img/logo.png,对应的磁盘路径是:/tmp/images/logo.png

六. location核心配置

location配置语法:​​location [ = | ~ | ~* | ^~ ] uri {...}​​,接着看一下这个配置规则

  • ​=​​​ :精确匹配,如:​​location = /images/ {...}​
  • ​~​​​:正则匹配,分区大小写,如:​​location ~ \.(jpg|gif)$ {.....}​
  • ​~*​​​ :正则匹配,不区分大小写,如:​​location ~* \.(jpg|gif)$ {......}​
  • ​^~​​​:匹配到即停止搜索, 如:​​location ^~ /images/ {......}​
  • 不带任何字符:如​​location / {......}​

这几种匹配的优先级:​​=​​​ > ​​^~​​​ >​​~​​​ > ​​~*​​ > 不带任何字符。

注意 : ​​location /haha/ {...}​​​ 和​​location ^~ /test/ {...}​​ 不可以同时出现。

最后这里还需要注意一点:关于 ​​location /haha {...}​​​ 和 ​​location /haha/ {...}​​区别:

先说相同点:​​nginx​​​在接受请求之后会在配置的​​root​​​目录下查找​​haha​​​目录下面的​​index.html​​​返回,但是​​/haha​​​这样的配置如果找不到​​index.html​​​文件会接着找​​haha​​​这个文件,存在的话,将输出​​haha​​​文件的内容。否则输出​​404​

七. 日志配置

​nginx​​​的日志有两种:​​access_log​​​和​​error_log​​:

  • 访问日志(​​access_log​​)主要记录客户端的请求。客户端向​​nginx​​服务器发起的每一次请求都记录在这里。客户端IP,浏览器信息,​​referer​​,请求处理时间,请求​​URL​​等都可以在访问日志中得到。
  • 错误日志(​​error_log​​)记录服务器和请求处理过程中的错误信息。

7.1. 访问日志

配置访问日志:

access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];

可以通过 ​​access_log off;​​ 设置之后当前作用域下的所有的请求日志都被关闭。

参数含义:

  • ​path​​指定日志的存放位置。
  • ​format​​​指定日志的格式。默认使用预定义的​​combined​​(后面介绍)。
  • ​buffer​​用来指定日志写入时的缓存大小。默认是64k。
  • ​gzip​​日志写入前先进行压缩。压缩率可以指定,从1到9数值越大压缩比越高,同时压缩的速度也越慢。默认是1。
  • ​flush​​​ 设置缓存的有效时间。如果超过​​flush​​指定的时间,缓存中的内容将被清空。
  • ​if​​条件判断。如果指定的条件计算为0或空字符串,那么该请求不会写入日志。

作用域:​​http​​​, ​​server​​​, ​​location​​​, ​​if in location​​​, ​​limit_except​

7.2. 错误日志

配置错误日志:

error_log file [level]

配置的作用域:​​main​​​, ​​http​​​, ​​mail​​​, ​​stream​​​, ​​server​​​, ​​location​

nginx默认配置:​​error_log logs/error.log error;​

错误日志的等级:​​debug​​​, ​​info​​​, ​​notice​​​, ​​warn​​​, ​​error​​​, ​​crit​​​, ​​alert​​​和 ​​emerg​

7.3. 日志格式

nginx预定义了名为combined的日志格式(没有自定义默认使用),默认的日志格式:

log_format combined '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';

日志格式可以包含​​公共变量​​,以及仅在日志写入时存在的变量,接着看一下这里面会用到的一些变量:

变量

含义

​$bytes_sent​

发送给客户端的总字节数

​$body_bytes_sent​

发送给客户端的字节数,不包含响应头大小

​$connection​

连接序列号

​$connection_requests​

当前通过连接发出的请求数量

​$msec​

日志写入时间

​$pipe​

如果请求是通过http流水线发送,则其值是:​​p​​​,否则为​​.​

​$request_length​

请求长度

​$request_time​

请求处理时间

​$status​

响应状态

​$time_iso8601​

标准格式本地时间

​$time_local​

通用日志格式下本地时间

​$http_referer​

请求的referer地址

​$http_user_agent​

客户端浏览器信息

​$http_x_forwarded_for​

当前段有代理服务器时,设置web节点记录客户端地址的配置。

​$remote_user​

客户端用户名称,针对启用了用户认证的请求

​$remote_addr​

客户端IP地址

​$request_url​

完整的请求地址

​nginx​​​默认的访问日志记录的内容相对比较单一,默认的格式也不方便后期做日志的统计分析,生产环境中通常将​​nginx​​​日志转换为​​json​​​日志,然后配合​​ELK​​​做日志收集、统计、分析。接着看一个​​log_format​​自定义日志的示例:

log_format json escape=json '{"@timestamp":"$time_iso8601",'
'"@version":"1",'
'"server_addr":"$server_addr",'
'"remote_addr":"$remote_addr",'
'"host":"$host",'
'"uri":"$uri",'
'"body_bytes_sent":$body_bytes_sent,'
'"bytes_sent":$body_bytes_sent,'
'"upstream_response_time":$upstream_response_timer,'
'"request":"$request",'
'"request_length":$request_length,'
'"request_time":$request_time,'
'"status":"$status",'
'"http_referer":"$http_referer",'
'"http_x_forwarded_for":"$http_x_forwarded_for",'
'"http_user_agent":"$http_user_agent"'
'}';

使用:

http {

log_format main '.......';

log_format json escape=json '.......';


server {
......
access_log /xxxx/access.json json;
}
}

扩展:IO 多路复用

nginx采用的就是IO多路复用模型,IO多路复用就是通过一种机制,一个进程可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。

优势:多进程和多线程技术相比,I/O多路复用技术的最大优势是系统开销小,系统不必创建进程/线程,也不必维护这些进程/线程,从而大大减小了系统的开销。

说起IO多路复用机制之前,会有BIO(同步阻塞)、NIO(同步非阻塞)两种机制,但他们都有问题。

  • BIO(同步阻塞):从字面意义上理解,当接受(accept)一个请求过来之后,在没有处理这个请求之前,将无法接受其他的请求,一直阻塞,这样就没法处理并发任务;此时可能会想如果开启多线程去处理呢?这样当接受请求之后,开启线程去处理,虽然比单线程方式有进步,但是随着请求增加,线程也会增加,会占用很大的内存空间,并且线程之间切换也很费资源。
  • NIO(同步非阻塞):这种方式就是接受一个请求之后,加到一个集合中,轮询这个集合,但是会出现CPU空转的问题

IO多路复用实现方式

IO多路复用用三种方式:​​select​​​、​​poll​​​和​​epoll​​。

三种基本原理查看这位博主的文章:​​https://learnku.com/articles/38414​

三种方式对比