01_Nginx配置文件详解

Nginx 服务器的各种配置指令的作用和用法。

Posted by silhouette on June 12, 2020

前言

书接上回,上一篇博客简单的介绍了一下Nginx及其安装,接下来,让我们详细学习Nginx服务器的各种配置指令的作用和用法。下面是本博客所参考链接

一、Nginx 配置文件详解

1.1 nginx.conf 配置文件

Nginx 安装目录下,其默认的配置文件都放在conf目录下,而主配置文件nginx.conf也在其中,后续对Nginx的使用基本都是对此配置文件进行相应的修改。

常见的配置文件有如下几个:

  • nginx.conf:应用程序的基本配置文件
  • mime.types:MIME类型关联的扩展文件
  • fastcgi.conf:与 fastcgi 相关的配置
  • proxy.conf:与 proxy 相关的配置
  • sites.conf:配置 Nginx 提供的网站,包括虚拟主机

具体结构见下图:

查看nginx.config文件,将注释等删掉后可以明显的发现,该配置文件分为三部分:

1.2 全局块

在配置文件开始到events块之间的内容,主要设置一些影响Nginx服务器整体运行的配置指令,主要有:

  1. 配置运行Nginx服务器的用户(组)

    # 指令格式:user user [group];
    # 		user:指定可以运行Nginx服务器的用户
    #       group:可选项,可以运行Nginx服务器的用户组
    user root;
    

    Tips:如果user指令不配置或者配置为user nobody nobody,则默认所有用户都可以启动Nginx进程

  2. 允许生成的worker process

    # 指令格式:worker_processes number | auto;
    # 	number:Nginx 进程最多可以产生的 worker processes
    # 	auto:Nginx进程将自动检测
    worker_processes  2;
    

    Tips:该指令是Nginx服务器实现并发处理服务的关键,worker_processes 值越大,可以支持的并发处理量也越多,但是会受到硬件、软件等设备的制约。

    Tips:启动 Nginx 的时候,会启动以 master 进程,这个进程不处理任何客户的请求,主要用来产生一个worker 进程,一个worker 进程来处理一个 request 请求。

  3. 进程PID 存放路径

    # 指令格式:pid file;
    #		file:指定存放路径和文件名称,默认路径是 logs/nginx.pid
    pid        logs/nginx.pid;
    

    Tips:Nginx进程是作为系统守护进程在运行,需要在某些文件中保存当前程序的主进程号,Nginx支持该保存文件路径的自定义。

  4. 日志存放路径

    # 指定格式:error_log file | stderr;
    # 	file;日志输出到某个文件file
    # 	stderr:日志输出到标准错误输出
    error_log  logs/error.log;
    error_log  logs/error.log  notice;
    error_log  logs/error.log  info;
    

1.3 events

events块涉及的指令主要影响Nginx服务器与用户的网络链接,常用的设置包括是否开始对多work process下的网络链接进行序列化,是否允许同时接受多个网络连接,选取哪种事件驱动模型来处理连接请求,每个work process可以同时支持的最大连接数等。

events {
		# 设置网络连接的序列化
		accept_mutex 	on | off;
		# 是否允许同时接受多个网络连接
		multi_accept 	on | off;
		# 事件驱动模型的选择
		# model 模型可选项包括:select、poll、kqueue、epoll、rtsig等
		use model;
		
		# 最大连接数的配置。默认值为512,表示允许每一个 worker process可以同时开启的最大连接数
    worker_connections  1024;
}

1.4 http

这里是nginx服务器配置中最频繁的部分,代理、缓存和日志定义等绝大多数功能和第三方模块的配置都在这里。

注意:http块也可以包括http全局快server块

1.4.1 http全局块

http全局块配置的指令包括文件引入、MIME-TYPE 定义、日志自定义、连接超时时间、单链接请求数上限等。

# 文件引入,将mime.types包含进来
include mime-types;
# mime-type定义,MIME-TYPE指的是网络资源的媒体类型,也即前端请求的资源类型
default_type mime-type;

# 自定义服务日志
#		path:自定义服务日志的路径+名称
#		format:可选项,自定义服务日志的字符串格式。其中可以使用log——format
access_log path [format]

# 允许sendfile 方式传输文件,默认为off
snedfile 		on |off;
# 若size >0,则nginx进程的每个worker process每次调用sendfile()传输的数据最不不能超过此指;若size=0则表示不限制。默认为0
sendfile_max_chunk 	size;

# 连接超时时间配置
#			timeout:表示server端对接连接的保持时间,默认是75秒
#			header_timeout:可选项,表示在对答豹纹头部的 Keep-Alive域设置超市时间:“Keep-Alive:timeout=header_timeout”
keepalive_timeout timeout [header_timeout];

# 单连接请求数上限
#			该指令用于限定用户通过某一个连接向Ngin服务器发起请求的次数
keepalive_requests number;

# 设置允许客户端请求的最大的单个文件字节数
client_max_body_size 128m;
# 设置客户端请求头的headerbuffer大小
client_header_buffer_size 512k;
# 设置客户端请求主体的headerbuffer大小
client_body_buffer_size  512k;
# 设置客户端请求中较大的消息头的缓存最大数量和大小
large_client_header_buffers 4 512k;
# 设置客户端请求头读取超时时间
client_header_timeout 60;
# 设置客户端请求主体读取超时时间。
client_body_timeout 60;
# 响应客户端的超时时间
send_timeout 60;


#配置Nginx的HttpGzip模块。这个模块支持在线实时压缩输出数据流。可通过./nginx -v查看是否安装了该模块
# 设置开启或者关闭gzip模块
gzip  on;
# 用来指定压缩的类型,无论是否指定,“text/html”类型总是会被压缩的;
gzip_types application/javascript text/css;
# 设置允许压缩的页面最小字节数,页面字节数从header头的Content-Length中获取。默认值是0,不管页面多大都进行压缩。
gzip_min_length 1k;
# 表示申请4个单位为16K的内存作为压缩结果流缓存,默认值是申请与原始数据大小相同的内存空间来存储gzip压缩结果
gzip_buffers 4 16k;
# 指定GZIP压缩比,1 压缩比最小,处理速度最快;9 压缩比最大,传输速度快,但处理最慢,也比较消耗cpu资源
gzip_comp_level 9;

Tips:cat mime.types来查看mime.types文件内容,就是一个types结构,里面包含了各种浏览器能够识别的MIME类型以及对应类型的文件后缀名字,

1.4.2 server块

这块和虚拟主机有密切关系,虚拟主机从用户角度看,和一台独立的硬件主机是完全一样的,该技术的产生是为了节省互联网服务器的硬件成本。

每一个http块可以包含多个server块,而每个server 块就相当于一个虚拟主机

而每个 server 块也分为全局server 块,以及可以同时包含多个 location 块

  • 全局server 块

    • 最常见的配置是本虚拟机的监听配置和本虚拟机的名称或IP配置

      # 配置网络监听
      #			配置监听具体IP和具体端口上的连接 --listen 192.168.30.201:8080;
      #			配置监听具体IP上所有端口的连接   --listen 192.168.31.201;
      # 		监听具体端口上的所有IP的连接     --listen 8080;
      listen IP[:PORT];
      listen PORT:
          
      # 基于名称和IP的虚拟主机配置
      # 	name可以有多个并列名称,而且此处的name支持正则表达式
      server_name 		name1 name2 ...
      server_name			IP地址;
      
  • location块

    • 一个 server 块可以配置多个 location 块

    • 这块的主要作用是基于 Nginx 服务器接收到的请求字符串(server_name/uri-string),对虚拟主机名称(也可以是IP别名)之外的字符串(例如 前面的 /uri-string)进行匹配,对特定的请求进行处理。地址定向、数据缓存和应答控制等功能,还有许多第三方模块的配置也在这里进行。

    • 该指令用于匹配URL,语法如下:

      location [ = | ~ | ~* | ^~ ] uri {
             
      }
      
      • =:用于不含正则表达式的 uri 前,要求请求字符串与 uri 严格匹配,如果匹配成功,就停止继续向下搜索并立即处理该请求。
      • ~:用于表示 uri 包含正则表达式,并且区分大小写
      • ~*:用于表示 uri 包含正则表达式,并且不区分大小写
      • ^~:用于不含正则表达式的 uri 前,要求 Nginx 服务器找到标识 uri 和请求字符串匹配度最高的 location 后,立即使用此 location 处理请求,而不再使用 location 块中的正则 uri 和请求字符串做匹配。

      注意:如果 uri 包含正则表达式,则必须要有~或者~*标识

1.4.3 upstream 块

upstream是Nginx 的HTTP Upstream 模块,这个模块通过一个简单的调度算法来实现客户端IP到后端服务器的负载均衡。

upstream tomcat1{
        server    192.168.30.77:8888;
}

Nginx 的负载均衡模块目前自持四种调度算法:

  1. 轮询(默认)

    • 每个请求按照时间顺序逐一分配到不同的后端服务器,如果后端服务器 down 掉,能自动剔除。
  2. weight

    • weight 代表权重,权重默认为 1,权重越高被访问的机率越高,主要用于后端每个服务器性能不均的情况下
    upstream server_pool{
    		server 192.168.5.21 weight=10;
    		server 192.168.5.22 weight=10;
    }
    
  3. ip_hash

    • 每个请求按照访问 IP 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决方案session 的问题
    upstream server_pool{
    		ip_hash;
    		server 192.168.5.21:80;
    		server 192.168.5.22:80;
    }
    
  4. fair(第三方)

    • 按后端服务器的响应时间来分配请求,响应时间短的优先分配
    upstream server_pool{
    		server 192.168.5.21:80;
    		server 192.168.5.22:80;
    		fair;
    }
    

1.5 Nginx 原理剖析

我们查看 nginx 进程时,总会看到这样两条进程,如下所示:

实际上在启动 Nginx 的时候,会启动以 master 进程,这个进程不处理任何客户的请求,主要用来产生一个worker 进程,一个worker 进程来处理一个 request 请求,当然worker可以有多个,可通过配置实现。流程如下所示:

那么worker时如何工作的呢?流程如下所示:

1.5.1 master-workers 机制的好处

  1. 可以使用nginx -s reload进行热部署,注意此时有任务的worker 不参与重启操作
  2. 首先,对于每个 worker. 进程来说,独立的进程,不需要枷锁,所以省略了锁带来的开销,同时在编程以及问题查找时,也会方便很多。其次,采用独立的进程,可以让互相之间不会影响,一个进程退出后,其他进程还在工作,服务不会中断,master 进程则很快启动新的worker 进程。当然,worker 进程的异常退出,肯定是程序有 BUG了,会导致当前 worker 上的所有请求失败,不会影响到所有请求,所以降低了风险。
    • 每个worker是独立的进程,所以有其中的一个 worker 出现问题,其他的worker 独立的,继续进行争抢,实现请求过程,不会造成服务中断。

1.5.2 worker数量的合理化设置

Nginx 同 redis 类似都采用了 io 多路复用机制每个 worker 都是一个独立的进程,但每个进程里只有一个主线程,通过异步非阻塞的方式来处理请求, 即使是千上万个请求也不在话 下。每个 worker 的线程可以把一个 cpu 的性能发挥到极致。所以 worker 数和服务器的 cpu 数相等是最为适宜的。设少了会浪费 cpu,设多了会造成 cpu 频繁切换上下文带来的损耗。

  • 连接数 worker_connection

    • 这个值是表示每个 worker 进程所能建立连接的最大值,所以,一个 nginx 能建立的最大连接数,应该是 worker_connections * worker_processes。

      • 即发送一个请求,最少占用 2 个连接数,如涉及到数据库连接等操作,最少得 4 个连接数
    • 最大连接数,对于 HTTP 请求本地资源来说 , 能够支持的最大并发数量是 worker_connections * worker_processes,如果是支持 http1.1 的浏览器每次访问要占两个连接。

      • 普通的静态访 问最大并发数是: worker_connections * worker_processes /2
      • 如果是 HTTP 作 为反向代理来说,最大并发数量应该是 worker_connections * worker_processes/4

      因为作为反向代理服务器,每个并发会建立与客户端的连接和与后端服 务的连接,会占用两个连接