C/C++编程:nginx的配置总结

1059 篇文章 286 订阅

运行中的nginx进程间的关系

在正常环境下,部署nginx都是使用一个master进程来管理多个worker进程。一般情况下,worker进程的数量和服务器上的CPU核心数相等。

  • master进程只负责监控worker进程
  • worker进程提供服务。

默认情况下,nginx的运行目录为/usr/local/nginx

$ tree
.
├── client_body_temp
├── conf
│   ├── fastcgi.conf
│   ├── fastcgi.conf.default
│   ├── fastcgi_params
│   ├── fastcgi_params.default
│   ├── koi-utf
│   ├── koi-win
│   ├── mime.types
│   ├── mime.types.default
│   ├── nginx.conf
│   ├── nginx.conf.default
│   ├── scgi_params
│   ├── scgi_params.default
│   ├── uwsgi_params
│   ├── uwsgi_params.default
│   └── win-utf
├── fastcgi_temp
├── html
│   ├── 50x.html
│   └── index.html
├── logs
│   ├── access.log
│   ├── error.log
│   └── nginx.pid
├── proxy_temp
├── sbin
│   └── nginx
├── scgi_temp
└── uwsgi_temp

9 directories, 21 files

在这里插入图片描述

问题:什么叫做【worker进程的数量和服务器上的CPU核心数相等】

回答:如果主机CPU核数为8,那么就需要配置8个worker进程。

问题:为什么要设置成【worker进程的数量和服务器上的CPU核心数相等】呢?

  • 这是nginx与apache等服务器的不同之处。
    • 在Apache上每个进程在一个时刻处理一个请求,因此,如果希望达到高并发,就要把Apache的进程或者线程数量设置得更短,通常会一个服务端有几百个工作进程,这样大量的进程间切换将带来无谓的系统资源消耗
    • 而nginx不是这样,一个worker进程可以同时处理的请求数只受限于内存大小。而且在架构设计上,不同的workder进程之间处理并发请求时几乎没有同步锁的限制,workder进程通常不会进入睡眠状态
  • 因此,【worker进程的数量和服务器上的CPU核心数相等】时,进程间切换的代价最小

问题:nginx是支持单进程(master进程)提供服务的,为什么实际部署的时候要按照master-worker的方式配置多个进程呢?

回答:主要原因有两个

  • 由于master进程不会对用户请求提供服务,只用于管理worker进程。所以master进程需要配置成唯一的,它仅仅专注于自己的纯管理工作,为管理员提供命令行服务。
    • master进程需要有较大的权限,一般用是root权限。
    • worker进程的权限要小于或等于master进程,这样master进程才可以完全的管理worker进程。当任意一个worker进程出现错误从而导致coredump时,master进程会立即启动新的worker进程继续服务
  • 多个worker进程处理互联网请求不仅可以提高服务的健壮性(一个worker进程出错后,不会影响其他worker进程),更重要的是,这样可以充分利用SMP多核架构,从而实现真正意义上的多核并行处理。

nginx配置的通用语法

nginx的配置文件其实是一个文本文件。比如:

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}

块配置项

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

events {   # 事件类相关的配置
    worker_connections  1024;
}


http {   # HTTP相关的配置
    include       mime.types;
    default_type  application/octet-stream;


    server {
        listen       80;
        server_name  localhost;

   
}

上面代码段中的events、http、server等都是块配置项。

  • 块配置项可以嵌套。内层块直接继承外层块
  • 当内外层块中的配置发生冲突时,究竟是以内层块还是外层块的配置为准,取决于解析这个配置项的模块

语法格式

配置项名
	配置项值
1 配置项值
2 …
	;
  • 首先,在行首的是配置项名
    • 这些配置项名必须是Nginx的某一个模块想要处理的,否则Nginx会认为配置文件出现了非法的配置项名。
    • 配置项名输入结束后,将以空格作为分隔符。
  • 其次是配置项值
    • 它可以是数字、字符串、正则表达式
    • 针对一个配置项,既可以只有一个值,也可以包含多个值
    • 配置项值之间由空格符来分隔
    • 如果配置项值中包括语法符号,比如空格符,那么需要使用单引号或双引号括住配置项值,否则Nginx会报语法错误。比如log_format main '$remote_addr - $remote_user [$time_local] "$request" '; (其中,remote_addr是一个变量,使用它的时候前面要加上$符号)
  • 最后,每行配置的结尾需要加上分号。

如果有一个配置项暂时需要注释掉,那么可以加“#”注释掉这一行配置。

注意:在执行configure命令时,我们已经把很多模块编译进了nginx中,但是是否启用这些模块,一般取决于配置文件中相应的配置项。

nginx服务的基本配置

nginx在运行时,至少必须加载几个核心模块和一个事件类模块。这些模块运行时所支持的配置项称为基本配置(所有其他模块运行时都要依赖这些配置项

基本配置项大致可以分为4类:

  • 用于调试、定位问题的配置项
  • 正常运行时的必须配置项
  • 优化性能的配置项
  • 事件类配置项

用于调试、定位问题的配置项

(1)是否以守护进程方式运行Nginx

  • 语法: daemon on|off;
  • 默认: daemon on;
  • 解释:
    • daemon是脱离终端并且在后台运行的进程。它脱离终端是为了避免进程执行过程中的信息在任何终端上显示。这样,进程就不会被终端信息打断。
    • nginx默认是daemon的,但是也提供了关闭daemon模式的选项,目的是为了方便跟踪调试nginx

(2)是否以master/worker方式工作

  • 语法: master_process on|off;
  • 默认: master_process on;
  • 解释:当需要调试跟踪nginx时,可以选择off。这样就不会fork出worker子进程来处理请求,而是用master进程自身来处理请求

(3)error日志选项

  • 语法:error_log filepath level
  • 默认: error_log logs/error.log error
  • 解释
    • pathfile参数可以是一个具体的文件
      • 默认为 logs/error.log ,最后将它定位到一个磁盘空间足够大的位置。
      • pathfile可以是/dev/null,这样就不会输出任何日志了,这也是关闭error日志的唯一手段
      • pathfile可以是stderr,这样日志会输出到标准错误文件
    • level是日志的输出级别
      • 取值范围是debug、info、notice、warn、error、crit、alert、emerg,从左至右级别依次增大
      • 当设定为一个级别时,大于或等于该级别的日志都会被输出到pathfile文件中,小于该级别的日志则不会输出。
      • 如果日志级别设定到debug,必须在configure时加入–with-debug配置项。

(4)是否处理几个特殊的调试点

  • 语法: debug_points[stop|abort]
  • 解释:
    • 一般不用
    • nginx在一些关键的错误逻辑中设置了调试点。
    • 如果设置了debug_points为stop,那么Nginx的代码执行到这些调试点时就会发出SIGSTOP信号以用于调试。
    • 如果debug_points设置为abort,则会产生一个coredump文件,可以使用gdb来查看Nginx当时的各种信息。

(5)仅对指定的客户端输出debug级别的日志。

  • 语法: debug_connection[IP|CIDR]
  • 解释:
    • 这个配置项实际上属于事件类配置,因此,它必须放在events{…}中才有效
    • 它的值可以是IP地址或CIDR地址,例如:
events {
debug_connection 10.224.66.14;
debug_connection 10.224.57.0/24;
}
    • 这样,仅仅来自以上IP地址的请求才会输出debug级别的日志,其他请求仍然沿用error_log中配置的日志级别。
    • 这个配置对修复Bug很有用,特别是定位高并发请求下才会发生的问题
    • 使用debug_connection前,需确保在执行configure时已经加入了–with-debug参数,否则不会生效。

(6)限制coredump核心转储文件的大小

  • 语法: worker_rlimit_core size
  • 解释:
    • 如果不加限制,那么可能一个core文件会达到几GB,这样随便coredumps几次就会把磁盘占满,从而引发严重问题

(7)指定coredump文件生成目录

  • 语法: working_directory path
  • 解释:
    • worker进程的工作目录。这个配置项的唯一用途就是设置coredump问所防止的目录
    • 因此,需确保worker进程有权限向working_directory指定的目录中写入文件。

正常运行的配置项

(1)定位环境变量

  • 语法:env VAR|VAR=VALUE
  • 作用:这个配置项可以让用户直接设置操作系统上的环境变量

(2)嵌入其他配置文件

  • 语法:include pathfile
  • 作用:
    • 将其他配置文件嵌入到当前的nginx.conf文件中
    • 它的参数既可以是绝对路径,也可以是相对路径(相对于Nginx的配置目录,即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文件

(4)nginx worker进程运行的用户以及用户组

  • 语法: user username[groupname];
  • 默认: user nobody nobody;
  • 解释:
    • user用于设置master进程启动之后,fork出的work进程运行在哪个用户和用户组下。
    • 当按照“user username;”设置时,用户组名与用户名相同。
    • 若用户在configure命令执行时使用了参数–user=username和–group=groupname,那么优先使用参数中指定的而不是配置文件中指定的

(5)设置一个worker进程可以打开的最大句柄描述符个数

  • 语法:worker_rlimit_nofile limit;

(6)限制信号队列

  • 语法: worker_rlimit_sigpending limit;
  • 解释:设置每个用户发往nginx的信号队列的大小。也就是说,当某个用户的信号队列满了,这个用户再发送的信号量会被丢掉

优化性能的配置项

(1)nginx worker进程个数

  • 语法:worker_processes number;
  • 默认:worker_processes 1;
  • 作用:在master/worker运行方式下,定义worker进程的个数
  • 解释:
    • worke进程的数量会直接影响性能,那么应该配置多少个worker线程呢?这与实际业务需求有关
    • 每个worker进程但是单线程的进程,它们会调用各个模块以实现各种功能。如果这些模块确认不会出现阻塞式调用,那么有多少个CPU内核就会配置多少个进程;如果会阻塞,那么就应该多配置一些worker进程
    • 多worker进程可以充分利用多核架构,但是worker进程的数量多余CPU内核数,那么会增大进程间切换带来的消耗。一般情况下,用户要配置与CPU内核数相等的worker进程,并且使用下面的worker_cpu_affinity配置来绑定CPU内核。

(2)绑定Nginx worker进程到指定的CPU内核

  • 语法:worker_cpu_affinity cpumask[cpumask…]
  • 问题:为什么要绑定CPU
  • 回答:如果多个worker进程都在抢同一个CPU,那么就会出现同步问题。而如果多个worker进程独享一个CPU,那么就在内核的调度策略上实现了完全的并发。
  • 实例。如果有4颗CPU内核,就可以进行如下配置:
worker_processes 4;
worker_cpu_affinity 1000 0100 0010 0001;
  • 注意: worker_cpu_affinity配置仅对Linux操作系统有效。Linux操作系统使用sched_setaffinity()系统调用实现这个功能。

(3)SSL硬件加速

  • 语法:ssl_engine device;
  • 解释:如果服务器上有SSL硬件加速设备,那么就可以进行配置以加快SSL协议的处理速度。可以用下面命令来查看是否有SSL硬件加速设备:
openssl engine -t

(4)系统调用gettimeofday的执行频率

  • 语法: timer_resolution t;
  • 说明:现在基本已经不用了
  • 解释:
    • 默认情况下,每次内核的事件调用(如epoll、select、poll、kqueue等)返回时,都会执行一次gettimeofday,实现用内核的时钟来更新nginx中的缓存时钟。在早期linux内核中,gettimeofday的执行代价比较大,因为中间需要从内核态到用户态的内存复制
    • 但是现在内核中,gettimeofday只是一次vsyscall,仅仅对共享内存页中的数据做访问,并不是通常的系统调用,代价并不大。
    • 不过,如果希望日志文件中每行打印的时间更准确,也可以使用它。

(5)nginx worker进程优先级设置

  • 语法: worker_priority nice;
  • 默认: worker_priority 0
  • 作用:用于设置worker进程的nice优先级
  • 解释:
    • 在Linux或其他类UNIX操作系统中,当许多进程都处于可执行状态时,将按照所有进程的优先级来决定本次内核选择哪一个进程执行。进程所分配的CPU时间片大小也与进程优先级相关,优先级越高,进程分配到的时间片也就越大(例如,在默认配置下,最小的时间片只有5ms,最大的时间片则有800ms)。这样,优先级高的进程会占有更多的系统资源。
    • 优先级由静态优先级和内核根据进程执行情况所做的动态调整(目前只有±5的调整)共同决定。nice值是进程的静态优先级,它的取值范围是–20~+19,–20是最高优先级,+19是最低优先级。因此,如果用户希望Nginx占有更多的系统资源,那么可以把nice值配置得更小一些,但不建议比内核进程的nice值(通常为–5)还要小。

事件类配置项

(1)是否打开accept锁

  • 语法: accept_mutex[on|off]
  • 默认: accept_mutext on
  • 解释:
    • accept_mutex是nginx的负载均衡锁,可以让多个worker进程轮流的、序列化的与新客户端建立TCP连接。
    • 当某一个worker进程建立的连接数量达到worker_connections配置的最大连接数的7/8时,会大大的减少该worker进程试图建立新TCP连接的机会,一次实现所有worker进程之上的客户端请求数尽量接近
    • accept锁默认是打开的,如果关闭它,那么建立TCP连接的耗时会更短,但是worker进程之间的负载会非常不均衡,因此不建议关闭它

(2)lock文件的路径

  • 语法: lock_file path/file;
  • 默认: lock_file logs/nginx.lock;
  • 解释:
    • accept_mutex可能需要这个lock文件,如果accept_mutex关闭,那么这个配置项无效
    • 如果打开片accept_mutex,并且由于编译程序、操作系统架构等原因导致nginx不支持原子锁,这时才会用文件锁实现accept锁,这样lock_file指定的lock文件才会生效

(3)使用accept锁后真正建立连接之间的延迟时间

  • 语法: accept_mutex_delay Nms;
  • 默认: accept_mutex_delay 500ms;
  • 解释:
    • 在使用accept锁之后,同一时间只有一个worker进程能够获取accept锁。
    • 这个accept锁不是阻塞锁,如果取不到会立即返回。
    • 如果有一个worker进程试图取accept锁而没有取到,它至少要等accept_mutex_delay定义的时间间隔之后才再次尝试获取锁

(4)批量建立新连接

  • 语法: multi_accept[on|off];
  • 默认: multi_accept off;
  • 解释:当事件模型通知有新连接时,尽可能的对本次调度中客户端发起的所有TCP请求都建立连接

(5)选择事件模型

  • 语法: use[kqueue|rtsig|epoll|/dev/poll|select|poll|eventport];
  • 默认: Nginx会自动使用最适合的事件模型

(6)每个worker的最大连接数

  • 语法: worker_connections number;
  • 解释:定义每个worker进程可以同时处理的最大连接数

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

静态web服务器的主要功能是由ngx_http_core_module模块实现的。

Nginx为配置一个完整的静态Web服务器提供了非常多的功能。其配置项主要可以分为8类

虚拟主机和请求的分发

  • 由于IP地址的数量有限,因此经常存在多个主机域名对应同一个IP的情况
  • 这时在nginx.conf中就可以按照server_name(对应用户请求中的主机域名)并通过server块来定义虚拟主机,每个server块就是一个虚拟主机,它只处理与之相对应的主机域名请求
  • 这样,一台服务器上的nginx就能以不同的方式处理访问不同主机域名的HTTP请求了

(1)nginx监听哪个端口

  • 语法: listen address:port[default(deprecated in 0.8.21)|default_server|[backlog=num|rcvbuf=size|sndbuf=size|accept_filter=filter|deferred|bind|ipv6only=[on|off]|ssl]];
  • 默认: listen 80;
  • 配置块: server
  • 语法说明:
    • default:
      • 将所在的server块作为整个web服务端的默认server块
      • 如果没有设置这个参数,那么将会以在nginx.conf中找到的第一个server块作为默认server块。
      • 为什么要设置默认虚拟主机?当一个请求无法匹配配置文件中的所有主机域名时,就会选中默认的虚拟主机
    • default_server:同上。
    • backlog=num:
      • 表示TCP中backlog队列的大小。默认为-1,表示不设置
      • 在TCP建立三次握手的过程中,进程还没有开始处理监听句柄,则是backlog队列将会放置这些新连接
      • 如果backlog已经满了,还有新的客户端试图通过三次握手建立TCP连接,这时客户端将会建立连接失败。
    • rcvbuf=size:设置监听句柄的SO_RCVBUF参数
    • sndbuf=size:设置监听句柄的SO_SNDBUF参数。
    • accept_filter:设置accept过滤器,只对FreeBSD操作系统有用。
    • deferred:
      • 在设置该参数之后,如果用户发起建立连接请求,并且完成了TCP的三次握手,内核也不会为了这次的连接调度worker进程来处理,只有用户真正的发送请求数据时(内核已经在网卡中收到请求数据包),内核才会唤醒worker进程来处理这个连接
      • 这个参数适用于大并发的情况下,它减轻了worker进程的负担。当请求数据来临时,worker进程才会开始处理这个连接。
      • 只有确认上面所说的应用场景符合自己的业务需求时,才可以使用deferred配置。
    • bind:绑定当前端口/地址对,如127.0.0.1:8000。只有同时对一个端口监听多个地址时才会生效。
    • ssl:在当前监听的端口上建立的连接必须基于SSL协议。
  • 示例:
listen 127.0.0.1:8000;
listen 127.0.0.1; #注意:不加端口时,默认监听80端口
listen 8000;
listen *:8000;
listen localhost:8000;


# 如果服务器使用IPv6地址
listen [::]:8000;
listen [fe80::1];
listen [:::a8c9:1234]:80;


listen 443 default_server ssl;
listen 127.0.0.1 default_server accept_filter=dataready backlog=1024;

(2)主机名称

  • 语法: server_name name[…];
  • 默认: server_name"";
  • 配置块: server
  • 解释:
    • server_name后可以跟多个主机名称,如server_name www.testweb.com 、download.testweb.com;
    • 在开始处理一个HTTP请求时,Nginx会取出header头中的Host,与每个server中的server_name进行匹配,以此决定到底由哪一个server块来处理这个请求。有可能一个Host与多个server块中的server_name都匹配,这时就会根据匹配优先级来选择实际处理的server块。server_name与Host的匹配优先级如下:
      • 首先选择所有字符串完全匹配的server_name,如www.testweb.com
      • 其次选择通配符在前面的server_name,如*.testweb.com
      • 再次选择通配符在后面的server_name,如www.testweb.*
      • 最后选择使用正则表达式才匹配的server_name,如~^.testweb.com$
    • 如果Host与所有的server_name都不匹配,这时将会按下列顺序选择处理的server块。
      • 优先选择在listen配置项后加入[default|default_server]的server块
      • 找到匹配listen端口的第一个server块
    • 如果server_name后跟着空字符串(如server_name"";),那么表示匹配没有Host这个HTTP头部的请求
    • Nginx正是使用server_name配置项针对特定Host域名的请求提供不同的服务,以此实现虚拟主机功能

(3)server_names_hash_bucket_size

  • 语法: server_names_hash_bucket_size size;
  • 默认: server_names_hash_bucket_size 32|64|128
  • 配置块: http、server、location
  • 解释:为了提高快速寻找到相应server name的能力,nginx使用散列表来存储server name。server_names_hash_bucket_size 设置每个散列桶占用的内存大小

(4)server_names_hash_max_size

  • 语法: server_names_hash_max_size size;
  • 默认: server_names_hash_max_size 512;
  • 配置块: http、server、location
  • 解释:
    • server_names_hash_max_size会影响散列表的冲突率。
    • server_names_hash_max_size越大,消耗的内存就越多,但散列key的冲突率则会降低,检索速度也更快。
    • server_names_hash_max_size越小,消耗的内存就越小,但散列key的冲突率可能增高。

(5)重定向主机名称的处理

  • 语法: server_name_in_redirect on|off
  • 默认: server_name_in_redirect on;
  • 配置块: http、server或者location
  • 解释:
    • 该配置需要配合server_name使用。
    • 当使用on时,表示在重定向请求时会使用server_name里配置的第一个主机名代替原本请求中的hoast头部
    • 当使用off时,表示在重定向请求时使用请求本身的host头部

(6)location

  • 语法:location[=|~|~*|^~|@]/uri/{...}
  • 配置块: server
  • 解释:
    • location会尝试根据用户请求中的URI来匹配上面的/uri表达式,如果可以匹配,就选择location{}块中的配置来处理用户请求

匹配规则:

1) =表示把URI作为字符串,以便与参数中的uri做完全匹配。例如:

location = / {
#只有当用户请求是/时,才会使用该location下的配置…
}

2)~表示匹配URI时是字母大小写敏感的
3)~*表示匹配URI时忽略字母大小写问题
4)^~表示匹配URI时只需要其前半部分与uri参数匹配即可。例如:

location ^~ images {
# 以images开始的请求都会匹配上…
}

5)@表示仅用于Nginx服务内部请求之间的重定向,带有@的location不直接处理用户请求。
6)在uri参数里可以用正则表达式的。比如:

location ~* \.(gif|jpg|jpeg)$ {
# 匹配以.gif、.jpg、.jpeg结尾的请求…
}

注意:

  • location是有顺序的,当一个请求有可能匹配多个location时,实际上这个请求会被第一个location处理。
  • 在以上各种匹配方式中,都只能表达为“如果匹配…则…”。如果需要表达“如果不匹配…则…”,就很难直接做到。有一种解决方法是在最后一个location中使用/作为参数,它会匹配所有的HTTP请求,这样就可以表示如果不能匹配前面的所有location,则由“/”这个location处理。例如:
location / {
# /可以匹配所有请求
}

文件路径相关配置

(1)以root方式设置资源路径

  • 语法: root path;
  • 默认: root html;
  • 配置块: http、server、location、if
  • 例子:
location /download/ {
	root optwebhtml;
	# 如果有一个请求URL是/download/index/test.html,那么返回服务器上optwebhtml/download/index/test.html文件的内容。
}

(2)以alias方式设置资源路径

  • 语法: alias path;
  • 配置块: location
  • 作用:和root作用相似,但是解读方式有区别。(待研究)

(3)访问首页

  • 语法: index file…;
  • 默认: index index.html;
  • 配置块: http、server、location
  • 解释:
    • 有时,访问站点时的URI是/,这时一般是返回网站的首页,可以用ngx_http_index_module模块提供的index配置实现
    • index后可以跟多个文件参数,Nginx将会按照顺序来访问这些文件,例如:
location {
	root path;
	index index.html /html/index.php /index.php;
	# 接收到请求后,Nginx首先会尝试访问path/index.php文件
	# 如果不能访问,在试图返回path/htmlindex.php文件的内容
	# ... 依此类推。
}

(4)根据HTTP返回码重定向页面

  • 语法:error_page code[code...][=|=answer-code]uri|@named_location
  • 配置块: http、server、location、if
  • 解释:当对于某个请求返回错误码时,如果匹配上了error_page中设置的code,则重定向到新的URI中
  • 实例:
error_page 404 404.html;
error_page 502 503 504 50x.html;
error_page 403 http://example.com/forbidden.html
;
error_page 404 = @fetch;

(5)是否允许递归使用error_page

  • 语法: recursive_error_pages[on|off];
  • 默认: recursive_error_pages off
  • 配置块: http、server、location

(6)try_files

  • 语法: try_files path1[path2]uri;
  • 配置块: server、location
  • 效果待研究

内存及磁盘资源的分配

(1)HTTP body值存储到磁盘文件中

  • 语法: client_body_in_file_only on|clean|off;
  • 默认: client_body_in_file_only off;
  • 配置块: http、server、location
  • 解释:
    • 当为on或者clean时,用户请求的HTTP body一律存储到磁盘文件中,即使只有0字节也会存储为文件
    • 该请求结束时,如果为on,则增文件不会被删除(有调试、定位问题的时候才可以这样干),当为clean时,则会删除文件

(2)HTTP body尽量写入到一个内存buffer中

  • 语法: client_body_in_single_buffer on|off;
  • 默认: client_body_in_single_buffer off;
  • 配置块: http、server、location
  • 解释:HTTP body尽量写到内存buffer中,只有body大小超过了下面client_body_buffer_size设置的值,才写到磁盘文件中

(3)存储HTTP头部的内存buffer大小

  • 语法: client_header_buffer_size size;
  • 默认: client_header_buffer_size 1k;
  • 配置块: http、server
  • 解释:
    • 定义正常情况下Nginx接收用户请求中HTTP header部分(包括HTTP行和HTTP头部)时分配的内存buffer大小。
    • 有时,请求中的HTTP header部分可能会超过这个大小,这时下面的large_client_header_buffers定义的buffer将会生效。

(4)存储超大HTTP头部的内存buffer大小

  • 语法: large_client_header_buffers number size;
  • 默认: large_client_header_buffers 48k;
  • 配置块: http、server
  • 解释:
    • large_client_header_buffers 定义了nginx接收一个超大HTTP头部请求的buffer个数和每个buffer的大小
    • 如果HTTP请求行(如GET/index HTTP/1.1)的大小超过上面的单个buffer,则返回"Request URI too large"(414)。
    • 请求中一般会有许多header,每一个header的大小也不能超过单个buffer的大小,否则会返回"Bad request"(400)。
    • 请求行和请求头部的总和不可以超过buffer个数*buffer大小。

(5)存储HTTP body的内存buffer大小

  • 语法: client_body_buffer_size size;
  • 默认: client_body_buffer_size 8k/16k;
  • 配置块: http、server、location
  • 解释:
    • 定义nginx接收HTTP包体的内存缓冲区大小。也就是说,HTTP包体会先接收到指定的这块缓存中,之后才决定是否写入磁盘。
  • 注意:如果用户请求中含有HTTP头部Content-Length,并且其标识的长度小于定义的buffer大小,那么Nginx会自动降低本次请求所使用的内存buffer,以降低内存消耗。

(6)HTTP包体的临时存放目录

  • 语法: client_body_temp_path dir-path[level1[level2[level3]]]
  • 默认: client_body_temp_path client_body_temp;
  • 配置块: http、server、location
  • 待研究

(7)connection_pool_size

  • 语法: connection_pool_size size;
  • 默认: connection_pool_size 256;
  • 配置块: http、server
  • 解释:
    • nginx对于每个建立成功的TCP连接会预先分配一个内存池。这个设置指定这个内存池的初始大小(即ngx_connection_t结构体中的pool内存池初始大小),用于减少内核对于小快内存的分配次数
    • 需慎重设置,因为更大的size会使服务器消耗的内存增多,而更小的size则会引发更多的内存分配次数。

(8)request_pool_size

  • 语法: request_pool_size size;
  • 默认: request_pool_size 4k;
  • 配置块: http、server
  • 解释
    • nginx开始处理HTTP请求时,将会为每个请求都分配一个内存池。size配置项将指定这个内存池的初始大小(即ngx_http_request_t结构体中的pool内存池初始大小),用于减少内核对于小快内存的分配次数
    • TCP连接关闭时会销毁connection_pool_size指定的连接内存池,HTTP请求结束时会销毁request_pool_size指定的HTTP请求内存池,但它们的创建、销毁时间并不一致,因为一个TCP连接可能被复用于多个HTTP请求。

网络连接的设置

(1)读取HTTP头部的超时时间

  • 语法: client_header_timeout time(默认单位:秒);
  • 默认: client_header_timeout 60;
  • 配置块: http、server、location
  • 解释:
    • 客户端与服务器建立连接之后开始接收HTTP头部,在这个过程中,如果在一个client_header_timeout 内没有读到客户端发来的字节,则认为超时,并向客户端返回408(“Request timed out”)响应。

(2)读取HTTP body的超时时间

  • 语法: client_body_timeout time(默认单位:秒);
  • 默认: client_body_timeout 60;
  • 配置块: http、server、location

(3)发送响应的超时时间

  • 语法: send_timeout time;
  • 默认: send_timeout 60;
  • 配置块: http、server、location
  • 解释:
    • 即nginx服务器向客户端发送了数据包,但是客户端一直没有去接收这个数据包。
    • 如果某个连接超过send_timeout 定义的超时时间,那么nginx将会关闭这个连接

(4)reset_timeout_connection

  • 语法: reset_timeout_connection on|off;
  • 默认: reset_timeout_connection off
  • 配置块: http、server、location
  • 解释:
    • 连接超时后将通过向客户端发送RST包来直接重置连接
    • 当这个选项on后,nginx会在某个连接超时后,不是使用正常情况下的四次握手来关闭TCP连接,而是直接向用户发送RST重置包,不再等待用户的应答,直接释放nginx服务端上关于这个套接字使用的所有缓存(比如TCP滑动窗口)
    • 相比正常的关闭方式,它使得服务器避免产生很多处于FIN_WAIT_1、 FIN_WAIT_2、TIME_WAIT状态的TCP连接。
    • 注意,使用RST重置包关闭连接会带来一些问题,默认情况下不会开启

(5)lingering_close

  • 语法: lingering_close off|on|always;
  • 默认: lingering_close on;
  • 配置块: http、server、location
  • 解释:控制nginx关闭用户连接的方式。
    • always表示关闭用户连接前必须无条件的处理连接上所有用户发送的数据
    • off表示关闭连接时完全不管连接上是否已经有准备就绪的来自用户的数据
    • on是中间,on是中间值,一般情况下在关闭连接前都会处理连接上的用户发送的数据,除了有些情况下在业务上认定这之后的数据是不必要的。

(6)lingering_time

  • 语法: lingering_time time;
  • 默认: lingering_time 30s;
  • 配置块: http、server、location
  • 解释:
    • lingering_close启用后,这个配置项对于上传大文件很有用
    • 上面提到,当用户请求的Content-Length大于max_client_body_size配置时,Nginx服务会立刻向用户发送413(Request entity too large)响应。
    • 但是,很多客户端可能不管413返回值,仍然持续不断地上传HTTPbody,这时,经过了lingering_time设置的时间后,Nginx将不管用户是否仍在上传,都会把连接关闭掉。

(7)lingering_timeout

  • 语法: lingering_timeout time;
  • 默认: lingering_timeout 5s;
  • 配置块: http、server、location
  • 解释:
    • lingering_close生效后,在关闭连接前,会检测是否有用户发送的数据到达服务器
    • 如果超过lingering_timeout时间后还没有数据可读,就直接关闭连接
    • 否则,必须在读取完连接缓冲区上的数据并丢弃掉后才会关闭连接

(8)对某些浏览器禁用keepalive功能

  • 语法: keepalive_disable[msie6|safari|none]…
  • 默认: keepalive_disablemsie6 safari
  • 配置块: http、server、location
  • 解释:
    • HTTP请求中的keepalive功能是为了让多个请求复用一个HTTP长连接,这个功能对服务器的性能提高是很有帮助的。、
    • 但有些浏览器,如IE 6和Safari,它们对于使用keepalive功能的POST请求处理有功能性问题。因此可以针对这些浏览器设置禁用

(9)keepalive超时时间

  • 语法: keepalive_timeout time(默认单位:秒);
  • 默认: keepalive_timeout 75;
  • 配置块: http、server、location
  • 解释:一个keepalive连接在闲置超过一定时间后(默认的是75秒),服务器和浏览器都会去关闭这个连接。nginx默认设置为75s自己去关闭,但是管不了浏览器,只能关闭自己的

(10)一个keepalive长连接上允许承载的请求最大数

  • 语法: keepalive_requests n;
  • 默认: keepalive_requests 100;
  • 配置块: http、server、location
  • 解释:一个keepalive连接上默认最多只能发送100个请求。

(11)tcp_nodelay

  • 语法: tcp_nodelay on|off;
  • 默认: tcp_nodelay on;
  • 配置块: http、server、location
  • 解释:确定对keepalive连接是否使用TCP_NODELAY选项。

(12)tcp_nopush

  • 语法: tcp_nopush on|off;
  • 默认: tcp_nopush off;
  • 配置块: http、server、location
  • 解释:
    • 在打开sendfile选项时,确定是否开启FreeBSD系统上的TCP_NOPUSH或Linux系统上的TCP_CORK功能。
    • 打开tcp_nopush后,将会在发送响应时把整个响应包头放到一个TCP包中发送。

MIME类型的设置

(1)MIME type与文件扩展的映射

  • 语法: type{…};
  • 配置块: http、server、location
  • 解释:定义MIME type到文件扩展名的映射。多个扩展名可以映射到同一个MIME type。例如:
types {
	text/html html;
	text/html conf;
	image/gif gif;
	image/jpeg jpg;
}

(2)默认MIME type

  • 语法: default_type MIME-type
  • 默认: default_type text/plain
  • 配置块: http、server、location
  • 解释:当找不到相应的MIME type与文件扩展名之间的映射时,使用默认的MIME type作为HTTP header中的Content-Type。

(3)types_hash_bucket_size

  • 语法: types_hash_bucket_size size;
  • 默认: types_hash_bucket_size 32|64|128;
  • 配置块: http、server、location
  • 解释:
    • 为了快速寻找到相应MIME type,Nginx使用散列表来存储MIME type与文件扩展名。
    • types_hash_bucket_size设置了每个散列桶占用的内存大小。

(4)types_hash_max_size

  • 语法: types_hash_max_size size;
  • 默认: types_hash_max_size 1024
  • 配置块: http、server、location
  • 解释:
    • types_hash_max_size影响散列表的冲突率。
    • types_hash_max_size越大,就会消耗更多的内存,但散列key的冲突率会降低,检索速度就更快
    • types_hash_max_size越小,消耗的内存就越小,但散列key的冲突率可能上升。

对客户端请求的限制

(1)按HTTP方法名限制用户请求

  • 语法: limit_except method…{…}
  • 配置块: location
  • 实例:
limit_except GET {  # 禁止GET方法和HEAD方法(禁止GET方法就意味着也禁止HEAD方法),但其他HTTP方法是允许的。
	allow 192.168.1.0/32;
	deny all;
}

(2)HTTP请求body的最大值

  • 语法: client_max_body_size size;
  • 默认: client_max_body_size 1m;
  • 配置块: http、server、location
  • 解释:
    • 浏览器在发送含有较大HTTP包体的请求时,其头部会有一个Content-Length字段,client_max_body_size是用来限制Content-Length所示值的大小的。
    • Nginx在收完包头后,发现Content-Length超过client_max_body_size定义的值,就直接发送413(“Request Entity Too Large”)响应给客户端

(3)对请求的限速

  • 语法: limit_rate speed;
  • 默认: limit_rate 0;
  • 配置块: http、server、location、if
  • 解释:
    • 对客户端请求限制每秒传输的字节数
    • 默认参数为0,表示不限速。
    • 针对不同的客户端,可以用$limit_rate参数执行不同的限速策略。比如:
server {
	if ($slow) {
		set $limit_rate 4k;
	}
}

(4) limit_rate_after

  • 语法: limit_rate_after time;
  • 默认: limit_rate_after 1m;
  • 配置块: http、server、location、if
  • 解释:
    • 表示nginx向客户端发送的响应长度超过limit_rate_after后才开始限速。比如:
limit_rate_after 1m;
limit_rate 100k;

文件操作的优化

(1)sendfile系统调用

  • 语法: sendfile on|off
  • 默认: sendfile off;
  • 配置块: http、server、location
  • 解释:
    • 设置为on时,sendfile可以减少内核态和用户态之间的两次内存复制
    • 这样就会从磁盘中读取文件后直接到内核态发送到网卡设备,提高了发送文件的效率

(2)AIO系统调用

  • 语法: aio on|off;
  • 默认: aio off;
  • 配置块: http、server、location
  • 解释:
    • 是否启用内核级别的异步文件IO功能
    • 注意,它与sendfile是互斥的

(3)directio

  • 语法: directio size|off;
  • 默认: directio off;
  • 配置块: http、server、location
  • 解释:
    • 使用O_DIRECT选项去读取文件,缓冲区大小为size,通常对大文件的读取速度有优化作用
    • 注意,它与sendfile功能是互斥的。

(4)directio_alignment

  • 语法: directio_alignment size;
  • 默认: directio_alignment 512;
  • 配置块: http、server、location
  • 解释:
    • 它与directio配合使用,指定以directio方式读取文件时的对齐方式。
    • 一般情况下,512B已经足够了, 但针对一些高性能文件系统,如Linux下的XFS文件系统,可能需要设置到4KB作为对齐方式。

(5)打开文件缓存

  • 语法: open_file_cache max=N[inactive=time]|off;
  • 默认: open_file_cache off;
  • 配置块: http、server、location
  • 解释:
    • 文件缓存会在内存中存储下面3种信息:
      • 文件句柄、文件大小和上次修改时间
      • 已经打开过的目录结构
      • 没有找到的或者没有权限操作的文件信息
    • 这样,通过读取缓存就减少了对磁盘的操作。
    • 该配置项后面跟3种参数。
      • max:表示在内存中存储元素的最大个数。当达到最大限制数量后,将采用LRU(Least Recently Used)算法从缓存中淘汰最近最少使用的元素
      • inactive:表示在inactive指定的时间段内没有被访问过的元素将会被淘汰。默认时间为60秒
      • off:关闭缓存功能
  • 例如:
open_file_cache max=1000 inactive=20s;

(6)是否缓存打开文件错误的信息

  • 语法: open_file_cache_errors on|off;
  • 默认: open_file_cache_errors off;
  • 配置块: http、server、location
  • 作用:是否在文件缓存中缓存打开文件时出现的找不到路径、没有权限等错误信息。

(7)不被淘汰的最小访问次数

  • 语法: open_file_cache_min_uses number;
  • 默认: open_file_cache_min_uses 1;
  • 配置块: http、server、location
  • 作用:
    • 它与open_file_cache中的inactive参数配合使用。
    • 如果在inactive指定的时间段内,访问次数超过了open_file_cache_min_uses指定的最小次数,那么将不会被淘汰出缓存。

(8)检验缓存中元素有效性的频率

  • 语法: open_file_cache_valid time;
  • 默认: open_file_cache_valid 60s;
  • 配置块: http、server、location
  • 说明:默认为每60秒检查一次缓存中的元素是否仍有效。

对客户端请求的特殊处理

(1)忽略不合法的HTTP头部

  • 语法: ignore_invalid_headers on|off;
  • 默认: ignore_invalid_headers on;
  • 配置块: http、server
  • 说明:
    • 如果将其设置为off,那么当出现不合法的HTTP头部时,Nginx会拒绝服务,并直接向用户发送400(Bad Request)错误。
    • 如果将其设置为on,则会忽略此HTTP头部。

(2)HTTP头部是否允许下划线

  • 语法: underscores_in_headers on|off;
  • 默认: underscores_in_headers off;
  • 配置块: http、server
  • 说明:默认为off,表示HTTP头部的名称中不允许带“_”(下划线)。

(3)对If-Modified-Since头部的处理策略

  • 语法: if_modified_since[off|exact|before];
  • 默认: if_modified_since exact;
  • 配置块: http、server、location
  • 解释:
    • 出于性能考虑,Web浏览器一般会在客户端本地缓存一些文件,并存储当时获取的时间。
    • 这样,下次向Web服务器获取缓存过的资源时,就可以用If-Modified-Since头部把上次获取的时间捎带上,而if_modified_since将根据后面的参数决定如何处理If-Modified-Since头部。
  • 语法参数:
    • off:表示忽略用户请求中的If-Modified-Since头部。这时,如果获取一个文件,那么会正常地返回文件内容。HTTP响应码通常是200。
    • exact:将If-Modified-Since头部包含的时间与将要返回的文件上次修改的时间做精确比较,如果没有匹配上,则返回200和文件的实际内容,如果匹配上,则表示浏览器缓存的文件内容已经是最新的了,没有必要再返回文件从而浪费时间与带宽了,这时会返回304 NotModified,浏览器收到后会直接读取自己的本地缓存。
    • before:是比exact更宽松的比较。只要文件的上次修改时间等于或者早于用户请求中的If-Modified-Since头部的时间,就会向客户端返回304 Not Modified。

(4)文件未找到时是否记录到error日志

  • 语法: log_not_found on|off;
  • 默认: log_not_found on
  • 配置块: http、server、location
  • 作用:
    • 此配置项表示当处理用户请求且需要访问文件时,如果没有找到文件,是否将错误日志记录到error.log文件中。
    • 这仅用于定位问题。

(5)merge_slashes

  • 语法: merge_slashes on|off;
  • 默认: merge_slashes on;
  • 配置块: http、server、location
  • 作用:
    • 此配置项表示是否合并相邻的“”
    • 例如,/test///a.txt,在配置为on时,会将其匹配为location/test/a.txt;如果配置为off,则不会匹配,URI将仍然是//test///a.txt。

(6)DNS解析地址

  • 语法: resolver address…;
  • 配置块: http、server、location
  • 作用: 设置DNS名字解析服务器的地址
  • 示例:
resolver 127.0.0.1 192.0.2.1;

(7)DNS解析的超时时间

  • 语法: resolver_timeout time;
  • 默认: resolver_timeout 30s;
  • 配置块: http、server、location

(8)返回错误页面时是否在Server中注明Nginx版本

  • 语法: server_tokens on|off;
  • 默认: server_tokens on;
  • 配置块: http、server、location
  • 作用:表示处理请求出错时是否在响应的Server头部中标明Nginx版本,这是为了方便定位问题。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值