一. 整体结构
nginx的配置位于nginx
安装目录的config
目录下,nginx
下除了nginx.conf
主配置文件之外,还有一些cgi
(通用网关接口协议程序的配置),相关信息阅读这片文件:
针对nginx
的配置文件拥有以下几个部分:
- 全局块:配置影响
nginx
全局的指令。一般有运行nginx服务的用户组,nginx
进程的pid
存放路径,日志存放路径,允许生成的worker
进程的数量等等; -
events
块:配置影响nginx
服务器或者用户的网路连接。包括每个进程的最大连接数、使用哪种事件驱动模型处理连接请求、是否允许同时接受多个网络连接或者网络连接序列化等等; -
http
块:可以嵌套多个server
,配置代理、缓冲和日志定义等功能和第三方模块配置; -
server
块:配置虚拟主机的相关参数,一个http
可以有多个server
; -
location
块:配置请求路由和页面处理
结构如图:
二. 配置模板
可以在官网查看所有的指令:https://nginx.org/en/docs/dirindex.html。
接着看下一个模板配置文件:
这里需要注意一下,如果server
比较多的话,我们一般不会把server
放到nginx.conf
这个主配置文件中:
这样就可以将conf.d
目录下的所有server
的配置文件加载到主配置文件中!主配置文件http
中就不需要配置server
了,这里面的server.conf
文件写法如下:
二. 全局配置
全局配置是只指在第一部分介绍的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
示例二:显示的定义default_server
配置nginx禁止ip访问 :这样可以防止别人恶意解析ip。
配置方法一:返回444,403,501等错误
配置方法二:跳到主页
5.3. root和alias配置
root
和alias
都可以后面跟路径参数,作为URI
到磁盘文件的映射,但是需要注意alias只能使用在location
中,但是root
可以在http
、server
、location
和if
中使用。
这个最打的区别在于URI
路径,root
会将定义的路径和URI
叠加;alias
则只取定义路径。
示例一:
此时如果访问:www.test.com/img/logo.png,对应的磁盘路径是:/tmp/images/img/logo.png
示例二:
此时如果访问: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 off;
设置之后当前作用域下的所有的请求日志都被关闭。
参数含义:
-
path
指定日志的存放位置。 -
format
指定日志的格式。默认使用预定义的combined
(后面介绍)。 -
buffer
用来指定日志写入时的缓存大小。默认是64k。 -
gzip
日志写入前先进行压缩。压缩率可以指定,从1到9数值越大压缩比越高,同时压缩的速度也越慢。默认是1。 -
flush
设置缓存的有效时间。如果超过flush
指定的时间,缓存中的内容将被清空。 -
if
条件判断。如果指定的条件计算为0或空字符串,那么该请求不会写入日志。
作用域:http
, server
, location
, if in location
, limit_except
7.2. 错误日志
配置错误日志:
配置的作用域: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的日志格式(没有自定义默认使用),默认的日志格式:
日志格式可以包含公共变量,以及仅在日志写入时存在的变量,接着看一下这里面会用到的一些变量:
变量 | 含义 |
| 发送给客户端的总字节数 |
| 发送给客户端的字节数,不包含响应头大小 |
| 连接序列号 |
| 当前通过连接发出的请求数量 |
| 日志写入时间 |
| 如果请求是通过http流水线发送,则其值是: |
| 请求长度 |
| 请求处理时间 |
| 响应状态 |
| 标准格式本地时间 |
| 通用日志格式下本地时间 |
| 请求的referer地址 |
| 客户端浏览器信息 |
| 当前段有代理服务器时,设置web节点记录客户端地址的配置。 |
| 客户端用户名称,针对启用了用户认证的请求 |
| 客户端IP地址 |
| 完整的请求地址 |
nginx
默认的访问日志记录的内容相对比较单一,默认的格式也不方便后期做日志的统计分析,生产环境中通常将nginx
日志转换为json
日志,然后配合ELK
做日志收集、统计、分析。接着看一个log_format
自定义日志的示例:
使用:
扩展:IO 多路复用
nginx采用的就是IO多路复用模型,IO多路复用就是通过一种机制,一个进程可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。
优势:多进程和多线程技术相比,I/O多路复用技术的最大优势是系统开销小,系统不必创建进程/线程,也不必维护这些进程/线程,从而大大减小了系统的开销。
说起IO多路复用机制之前,会有BIO(同步阻塞)、NIO(同步非阻塞)两种机制,但他们都有问题。
- BIO(同步阻塞):从字面意义上理解,当接受(accept)一个请求过来之后,在没有处理这个请求之前,将无法接受其他的请求,一直阻塞,这样就没法处理并发任务;此时可能会想如果开启多线程去处理呢?这样当接受请求之后,开启线程去处理,虽然比单线程方式有进步,但是随着请求增加,线程也会增加,会占用很大的内存空间,并且线程之间切换也很费资源。
- NIO(同步非阻塞):这种方式就是接受一个请求之后,加到一个集合中,轮询这个集合,但是会出现CPU空转的问题
IO多路复用实现方式
IO多路复用用三种方式:select
、poll
和epoll
。
三种基本原理查看这位博主的文章:https://learnku.com/articles/38414
三种方式对比