Fork me on GitHub

Nginx配置文件

  Nginx是lgor Sysoev为俄罗斯访问量第二的rambler.ru站点设计开发的。从2004年发布至今,凭借开源的力量,已经接近成熟与完善。
  Nginx功能丰富,可作为HTTP服务器、反向代理服务器、邮件服务器。支持FastCGI、SSL、Virtual Host、URL Rewrite、Gzip等功能。并且支持很多第三方的模块扩展。
Nginx的稳定性、功能集、示例配置文件和低系统资源的消耗让他后来居上,在全球活跃的网站中有12.18%的使用比率,大约为2220万个网站。

Nginx常用功能

Http代理,反向代理

  作为web服务器最常用的功能之一,尤其是反向代理。
  这里我给来2张图,对正向代理与反向代理做个诠释,具体细节,大家可以翻阅下资料。
  
  Nginx在做反向代理时,提供性能稳定,并且能够提供配置灵活的转发功能。Nginx可以根据不同的正则匹配,采取不同的转发策略,比如图片文件结尾的走文件服务器,动态页面走web服务器,只要你正则写的没问题,又有相对应的服务器解决方案,你就可以随心所欲的玩。并且Nginx对返回结果进行错误页跳转,异常判断等。如果被分发的服务器存在异常,他可以将请求重新转发给另外一台服务器,然后自动去除异常服务器。

负载均衡

  Nginx提供的负载均衡策略有2种:内置策略和扩展策略。内置策略: 轮询,加权轮询,Ip hash。扩展策略,就天马行空,只有你想不到的没有他做不到的啦,你可以参照所有的负载均衡算法,给他一一找出来做下实现。

web缓存

  Nginx可以对不同的文件做不同的缓存处理,配置灵活,并且支持FastCGI_Cache,主要用于对FastCGI的动态程序进行缓存。配合着第三方的ngx_cache_purge,对制定的URL缓存内容可以的进行增删管理。


Nginx配置文件结构

  如果你下载好啦,你的安装文件,不妨打开conf文件夹的nginx.conf文件(Mac默认在/usr/local/nginx/),Nginx服务器的基础配置,默认的配置也存放在此。

nginx配置的通用语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
user nobody;
worker_processes 8;
error_log /var/log/nginx/error.log error;
# pid logs/nginx.pid;
events {
use epoll;
worker_connections 50000;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr [$time_local] "$request" '
'$status $bytes_sent "$http_referer" '
access_log logs/access.log main buffer=32k;
... ...
}

  1.全局块:配置影响nginx全局的指令。一般有运行nginx服务器的用户组,nginx进程pid存放路径,日志存放路径,配置文件引入,允许生成worker process数等。
  2.events块:配置影响nginx服务器或与用户的网络连接。有每个进程的最大连接数,选取哪种事件驱动模型处理连接请求,是否允许同时接受多个网路连接,开启多个网络连接序列化等。
  3.http块:可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。如文件引入,mime-type定义,日志自定义,是否使用sendfile传输文件,连接超时时间,单连接请求数等。
  4.server块:配置虚拟主机的相关参数,一个http中可以有多个server。
  5.location块:配置请求的路由,以及各种页面的处理情况。

块配置项

  块配置项由一个 块配置项名 和一个 大括号 组成。具体示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
events {
... ...
}
http {
upstream backend {
server 127.0.0.1:8080;
}
server {
... ...
location /webstatic {
gzip off;
}
}
}

  上面代码段中的events、http、server、location、upstream等都是块配置项。
  块配置可以嵌套,内层块直接继承外层块。块内配置项冲突的处理方法在后面讲。

配置项的语法格式

  最基本的配置项语法格式如下:
  配置项名 配置项值1 配置项值2 ...;
  1.配置项名:在行首。这些配置项名 必须 是Nginx的某一模块想要处理的,否则Nginx会认为配置文件出现了非法的配置项名。配置项名输入结束后,将以空格作为分隔符。
  2.配置项值:可以是数字或字符串(包括正则表达式)。一个配置项值对应的值有多少个,取决于解析这个配置项的模块。我们必须根据某个Nginx模块对一个配置项的约定来更改配置项,下文再介绍。
  3.每行配置的结尾需要加上分号。

  如果配置项值中包括语法符号,比如空格符,那么需要使用单引号或双引号 括住配置项值,否则Nginx会报语法错误。如
  log_format main ‘$remote_addr [$time_local] “$request” ‘

配置项的注释

  注释符号位#

配置项的单位

  大部分模块遵循一些通用的规定,如指定空间大小时不用每次都定义到字节、指定时间不用精确到毫秒。
  当指定空间大小时,可以使用K或k
  当指定时间时,可以使用 ms(毫秒)、s(秒)、m(分钟)、h、d、w(周,包含7天)、M、y

在配置中使用变量

  有些模块允许在配置项中使用变量,如在日志记录部分,具体示例如下:
  log_format main '$remote_addr [$time_local] "$request" '
  其中,remote_addr是一个变量,使用它的时候前面要加上$符号。这种变量只有少数模块支持,并不是通用的。


Nginx服务的基本配置

  Nginx在运行时,至少必须要加载几个核心模块和一个事件类模块。这些模块运行时所支持的配置项称为 基本配置。所有其他模块执行都依赖的配置项。
  按照用户使用时的预期功能分成4类:
  1.用于调试、定位问题的配置项
  2.正常运行的必备配置项
  3.优化性能的配置项
  4.事件类配置项(有些事件类配置归纳到优化性能类,这是因为它们虽然也属于events{}块,但作用是优化性能)   

用于调试进程和定位问题的配置项

1.是否以守护进程方式运行Nginx
  语法:daemon on | off;
  默认:daemon on 
  守护进程是脱离终端并且在后台运行的进程。它脱离终端是为了避免进程执行过程中的信息在任何终端上显示,这样一来,进程也不会被任何终端所产生的信息所打断。  
  不过Nginx还是提供了关闭守护进程的模式,之所以提供这种模式,是为了方便跟踪调试Nginx,毕竟用gdb调试进程时最烦琐的就是如何继续跟进fork出的子进程了。
  
2.是否以 master/worker 方式工作
  语法:master_process on | off;
  默认:master_process on 
  与daemon配置相同,提供master_process配置也是为了方便跟踪高度Nginx。如果用off关闭了master_proces方式,就不会fork出worker子进程来处理请求,而是调用master自身进程来处理请求。

3.error日志的设置
  语法:error_log /path/file level;
  默认:error_log logs/error.log error 
  /path/file参数可以是一个具体的文件,也可以是/dev/null这样就不会输出任何日志,这也是关闭error日志的唯一手段。也可以是stderr,这样日志会输出到标准错误文件中。
  level是日志的输出级别,取值范围是debug、info、notice、warn、error、crit、alert、emerg,从左至右级别依次增大。当设定一个级别时,>=该级别的日志都会被输出。如设定为error时,
error、crit、alert、emerg级别的日志都会输出。
  如果日志级别设定到debug,必须在configure时加入--with-debug配置项。

4.仅对指定的客户端输出debug级别的日志
  语法:debug_connection [IP|CIDR];
  这个配置项实际上属于事件类配置,因此,它必须放在events{…}中才有效。它的值可以是IP地址或CIDR地址,如

1
2
3
4
events {
debug_connection 10.224.66.14;
debug_connection 10.224.57.0/24;
}

  这样,仅仅来自以上IP地址的请求才会输出debug级别的日志,其他请求仍然沿用error_log中配置的日志级别。
  这个配置对修复bug很有用,特别是定位高并发请求下才会发生的问题。

使用debug_connection前,需确保在执行configure时已经加入了 –with-debug 参数,否则不会生效。

5.限制coredump核心转储文件的大小
  语法:worker_rlimit_core size;
  在Linux系统中,当进程发生错误或收到信号而终止时,系统会将进程执行时的内存内容写入一个文件(core文件),以作为调试之用,即 核心转储(core dumps)。可以从core文件获取当时的堆栈,寄存器信息等,帮助我们定位问题。但这种core文件如果不加以限制,可能达到几个G,会浪费磁盘,通过worker_rlimit_core可以限制core文件的大小。

6.指定 coredump 文件的生成目录
  语法:working_directory path;
  worker 进程的工作目录。这个配置的唯一用途就是设置coredump文件所放置的目录,协助定位问题。因此需确保worker进程有权限向working_directory指定的目录中写入文件。

正常运行的配置项

1.定义环境变量
  可以让用户直接设置操作系统上的环境变量
  语法:env VAR | VAR=VALUE;
  VAR 是变量名,VALUE 是目录;
  这个配置项可以让用户直接设置操作系统上的环境变量,如:env TEASTPATH=/tmp/

2.嵌入其他配置文件
  语法:include /path/file;
  include 配置项可以将其他配置文件嵌入到 Nginx 的 nginx.conf 文件中,不加path的话,指的是相对路径(相对于nginx.conf所在的目录);如
  include mime.types;
  include vhost/*.conf; # 可以是含有通配符的文件名

3.pid 的文件路径
  语法:pid path/file;
  默认:pid logs/nginx.pid;
  保存 master 进程 ID 的 pid 文件存放路径。默认与configure执行时间的参数”–pid-path“所指定的路径是相同的,也可以随时修改,但应该确保Nginx有权在相应的目标中创建pid文件,该文件直接影响Nginx是否可以运行

4.Nginx worker 运行的用户及用户组
  语法:user username [groupname];
  默认:user nobody nobody;
  设置master进程启动以后,fork出的worker进程运行在哪个用户和用户组下。 当按照”user username;”设置时,用户组名与用户名相同。
  若用户在configure命令执行时使用了参数--user=username--group=groupname,此时nginx.conf将使用参数中指定的用户和用户组。

5.指定 Nginx worker进程可打开最大句柄个数
  语法:worker_rlimit_nofile limit;

6.限制信号队列
  语法:worker_rlimit_sigpending limit;
  设置每个用户发给 Nginx 的信号队列大小,超出则丢弃;

优化性能配置项

1.Nginx worker 进程的个数
  语法:worker_process number;
  默认:worker_process 1;
  worker进程的数量会直接影响性能。配置多少个worker与业务需求有关。
  每个worker进程都是单线程的进程,它们会调用各个模块实现多种多样的功能。如果这些模块确认不会出现阻塞式的调用,那么有多少CPU内核就应该配置多少个进程;反之,如果有可能出现阻塞式调用,那么需要配置稍多一些的worker进程。
  多worker进程可以充分利用多核系统构架,但若worker进程的数量多于CPU内核数,会增大进程间切换带来的消耗(Linux是抢占式内核)。一般情况下,用户要配置与CPU内核数相等的worker进程,并使用下面的worker_cpu_affinity配置来绑定CPU内核。

2.绑定 Nginx worker 进程到指定的 CPU 内核
  语法:worker_cpu_affinity cpumask [cpumask...]
  为什么要绑定worker进程到指定的CPU内核呢?假定每一个worker进程都是非常繁忙的,如果多个worker进程都在抢同一个CPU,那么就会出现同步问题。反之,如果每个worker进程独享一个CPU,就可以在内核的调度策略上实现了完全的并发。
  如果有4颗CPU内核,就可以进行如下配置:
  worker_processes 4
  worker_cpu_affinity 1000 0100 0010 0001
  仅对linux系统有效

3.SSL 硬件加速
  语法:ssl_engine device;
  服务器如果有SSL硬件加速设备,可以配置以加快SSL协议的处理速度.用户可以使用OpenSSL提供的命令来查看是否有SSL硬件加速设备:
  openssl engine -t

4.系统调用 gettimeofday 的执行频率
  语法:timer_resolution t;

5.Nginx worker 进程优先级设置
  语法:worker_priority nice;
  默认:worker_priority 0;

事件类配置项

1、是否打开accept锁
  语法格式:accept_mutex [on | off];
  负载均衡锁,可以让多个worker进程轮流地、序列化地与新的客户端建立TCP连接。
  accept锁默认是打开的,如果关闭它,那么则建立TCP连接的耗时会更短,但worker进程之间的负载会非常不均衡,因此不建议关闭它。

2、lock文件的路径
  语法格式:lock_file path/file;

3、使用accept锁后到真正建立连接之间的延迟时间
  语法格式:accept_mutex_delay Nms;
  这个锁是非阻塞锁,即如果取不到则立即返回,至少要等Nms时才能再次试图取锁

4、批量建立新连接
  语法格式:multi_accept [on | off];

5、选择事件模型
  语法格式:use [kqueue | rtisg | epoll | /dev/poll | select | poll | eventport];
  Linux的事件驱动模型有poll、select、epoll,其中epoll性能最高

6、每个worker进程可以同时处理的最大连接数
  语法格式:worker_connections number;


用HTTP 核心模块配置一个静态Web服务器

  静态Web服务器的主要功能由ngx_http_core_module模块实现,当然,一个完整的静态Web服务器还有许多功能是由其他的HTTP模块实现的。本节主要讨论如何配置一个包含基本功能的Web服务器。文中主要说明ngx_http_core_module模块提供的配置项及变量的用法。
  除了之前提到的基本配置项外,一个典型的静态Web服务器还会包含多个server块和location块,例如:

1
2
3
4
5
6
7
8
9
10
http {
gzip on;
upstream {
... ...
}
server {
listen localhost:80;
...
}
}

  所有的HTTP配置项都必须直属于http块、server块、location块、upstream块或if块等。Nginx为配置一个完整的静态Web服务器提供了非常多的功能,下面把这些配置项分为以下8类进行详述:虚拟主机与请求的分发、文件路径的定义、内存及磁盘资源的分配、网络连接的设置、MIME类型的设置、对客户端请求的限制、文件操作的优化、对客户端请求的特殊处理。

虚拟主机与请求分发

  由于IP地址的数量有限,因此经常存在多个主机域名对应着同一个IP地址的情况,这时在nginx.conf中就可以按照server_name并通过server块来定义虚拟主机,每个server块就是一个虚拟主机,它只处理与之对应的主机域名请求。这样,一台服务器上的Nginx就能以不同的方式处理访问不同主机域名的HTTP请求了。
1.监听端口
  语法:listen address:port[default|default_server | [backlong=num | rcvbuf=size | sndbuf=size | accept_filter | deferred | bind | ipv6only=[on | off] | ssl]];
  默认:listen:80;
  配置块范围:server
  listen参数决定Nginx服务如何监听端口,如
  listen 127.0.0.1:8000;
  listen 127.0.0.1; # 不加端口,默认监听80端口
  listen *:8000;
  listen 8000;
  listen localhost:8000;

2.主机名称
  语法:server_name name[...];
  默认:server_name "";
  配置块范围:server
  在开始处理一个HTTP请求时,Nginx会取出header头中的Host,与每个server中的server_name进行匹配(server_name后可以跟多个主机名),以此决定到底由哪一个server块来处理这个请求。

3.server name 是使用散列表存储的
  每个散列桶占用内存大小
  语法:server_names_hash_bucket_size size;
  默认:server_names_hash_bucker_size 32|64|128;

3.散列表最大bucket数量 ,这个大小会影响散列表的冲突率。越大,内存消耗越多,但冲突率则越小,检索速度也更快
  语法:server_names_hash_max_size size;
  默认:server_names_hash_max_size 512;
  配置块范围:server、http、location

4.处理重定向主机名,打开时表示在重定向请求时会使用server_name里配置的第一个主机名代替原先请求中的Host头部
  语法:server_name_in_redirect on | off;
  默认:server_name_in_redirect on;
  配置块范围:server、http、location

5.location
  语法:location[= | ~ | ~* | ^~ | @] /uri/ {}
  配置块:server
  location尝试根据用户请求中的URI来匹配 /uri表达式,若匹配成功,则执行{}里面的配置来处理用户请求.
  以下是location的一般配置项
  1)= 表示把URI作为字符串,以便与参数中的uri做完全匹配。
  2)~ 表示匹配URI时是字母大小写敏感的。
  3)~* 表示匹配URI时忽略字母大小。
  4)^~ 表示匹配URI时只需要其前半部分与uri参数匹配即可。如
   localtion ^~ /images/ {
     # 以/images/开始的请求都会匹配上
   }
  5)@ 表示仅用于Nginx服务内部请求之间的重定向,带有@的location不直接处理用户请求。

  当然,在uri参数里是可以用正则表达式的,如
   localtion ~* \.(gif|jpg|jpeg)$ {      # 匹配以 .gif、.jpg、.jpeg结尾的请求    }
  注意,location是有顺序的,当一个请求有可能匹配多个location时,实际上这个 请求会被第一个location处理
  在以上的各种匹配方式中,都只能表达为“如果匹配…则…”。如果需要表达”如果不匹配…则…”,就很难直接做到。有一种解决方法是在最后一个location中使用/作为参数,它会匹配所有的HTTP请求,这样就可以表示如果不能匹配前面的所有location,则由”/“这个location处理。如:
   localtion / {
     # 匹配所有请求
   }

文件路径的定义

1.root方式设置资源路径
  语法:root path;
  默认:root html;
  配置块范围:server、http、location、if
  如字义资源文件相对于HTTP请求的根目录
  localtion /download/ {
    root /opt/web/html/;
  }
  如果有一个请求的URI是 /download/index/test.html,那么Web服务器将会返回服务器上/opt/web/html/download/index/test.html文件的内容。

以alias方式设置资源路径
  语法:alias path;
  配置块范围:location

2.访问主页
  语法:index file…;
  默认:index index.html;
  配置块范围:http、server、location

3.根据HTTP返回码重定向页面
  语法:error_page code [code...] [= | =answer-code] uri | @named_location;
  配置块范围:server、http、location、if

4.是否允许递归使用error_page
  语法:recursive_error_pages [on | off];
  配置块范围:http、server、location

5.try_files
  语法:try_files path1 [path2] uri;
  配置块范围:server、location

-----------------本文结束,感谢您的阅读-----------------