signed

QiShunwang

“诚信为本、客户至上”

nginx基础配置

2021/6/3 15:56:39   来源:

ngixn的配置

  • 运行中的Nginx进程间的关系
    • master进程的作用
    • worker进程
  • Nginx服务的基本配置
    • 用于调试进程和定位问题的配置项
    • 正常运行的配置项
    • 优化性能的配置项
    • event 事件类配置项
  • 用HTTP核心模块配置一个静态Web服务器
    • 虚拟主机与请求的分发
    • 文件路径的定义
    • 内存及磁盘资源的分配
    • 网络连接的设置
    • MIME类型的设置
    • 对客户端请求的限制
    • 文件操作的优化
    • 对客户端请求的特殊处理
  • 用HTTP proxy module配置一个反向代理服务器
    • 负载均衡的基本配置
    • 反向代理的基本配置

运行中的Nginx进程间的关系

在正式提供服务的产品环境下,部署Nginx时都是使用一个master进程来管理多个worker 进程,一般情况下,worker进程的数量与服务器上的CPU核心数相等。每一个worker进程都是工作的,它们在提供互联网服务,master进程则只有一个任务,那就是负责监控管理worker 进程。worker进程之间通过共享内存、原子操作等一些进程间通信机制来实现负载均衡等功能。

master进程的作用

由于master进程不会对用户请求提供服务,只用于管理真正提供服务的worker进程, 所以master进程可以是唯一的,它仅专注于自己的管理工作,为管理员提供命令行服务, 包括诸如启动服务、停止服务、重载配置文件、平滑升级程序等。master进程需要拥有较大 的权限,例如,通常会利用root用户启动master进程。worker进程的权限要小于或等于master 进程,这样master进程才可以完全地管理worker进程。当任意一个worker进程出现错误从而导致coredump时,master进程会立刻启动新的worker进程继续服务。

worker进程

多个worker进程处理互联网请求不但可以提高服务的健壮性(一个worker进程出错后,其他worker进程仍然可以正常提供服务),最重要的是,这样可以充分利用现在常见的SMP多核架构,从而实现微观上真正的多核并发处理。因此,用一个进程(master进程)来处理互联网请求肯定是不合适的。另外,为什么要把worker进程数量设置得与CPU核心数量一致呢?这正是Nginx与Apache服务器的不同之处。在Apache上每个进程在一个时刻只处理一个请求,因此,如果希望Web服务器拥有并发处理的请求数更多,就要把Apache的进程或线程数设置得更多,通常会达到一台服务器拥有几百个工作进程,这样大量的进程间切换将带来无谓的系统资源消耗。而Nginx则不然,一个worker进程可以同时处理的请求数只受限于内存大小,而且在架构设计上,不同的worker进程之间处理并发请求时几乎没有同步锁的限制,worker进程通常不会进入睡眠状态,因此,当Nginx上的进程数与CPU核心数相等时(最好每一个worker进程都绑定特定的CPU核心),进程间切换的代价是最小的。
在这里插入图片描述
在这里插入图片描述

Nginx服务的基本配置

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

  1. 是否以守护进程方式运行Nginx
    语法: daemon on|off;
    默认: daemon on;
    守护进程(daemon)是脱离终端并且在后台运行的进程。脱离终端是为了避免进程执行过程中的信息在任何终端上显示,这样一来,进程也不会被任何终端所产生的信息所打断。Nginx毫无疑问是一个需要以守护进程方式运行的服务,因此,默认都是以这种方式运行的。
    不过Nginx还是提供了关闭守护进程的模式,之所以提供这种模式,是为了方便跟踪调 试Nginx,毕竟用gdb调试进程时最烦琐的就是如何继续跟进fork出的子进程了。

  2. 是否以master/worker方式工作
    语法: master_process on|off;
    默认: master_process on;

  3. error日志的设置
    语法: error_logpathfile level;
    默认: error_log logs/error.log error;

  4. 是否处理几个特殊的调试点
    语法: debug_points[stop|abort]
    这个配置项也是用来帮助用户跟踪调试Nginx的。它接受两个参数:stop和abort。通常不会使用这个配置项。

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

  6. 限制coredump核心转储文件的大小
    语法: worker_rlimit_core size;

  7. 指定coredump文件生成目录
    语法: working_directory path;

正常运行的配置项

  1. 定义环境变量
    语法: env VAR|VAR=VALUE
    这个配置项可以让用户直接设置操作系统上的环境变量
  2. 引入其他配置文件
    语法: include pathfile;
    include配置项可以将其他配置文件嵌入到当前的nginx.conf文件中,它的参数既可以是绝 对路径,也可以是相对路径(相对于Nginx的配置目录,即nginx.conf所在的目录)
  3. pid文件的路径
    语法: pid path/file;
    默认: pid logs/nginx.pid;
  4. Nginx worker进程运行的用户及用户组
    语法: user username[groupname];
  5. 设置一个worker进程可以打开的最大文件句柄数。
    语法: worker_rlimit_nofile limit;
  6. 限制信号队列
    语法: worker_rlimit_sigpending limit;
    设置每个用户发往Nginx的信号队列的大小。也就是说,当某个用户的信号队列满了,
    这个用户再发送的信号量会被丢掉。

优化性能的配置项

  • Nginx worker进程个数
    语法: worker_processes number;
    默认: worker_processes 1;
    在master/worker运行方式下,定义worker进程的个数。
    worker进程的数量会直接影响性能。那么,用户配置多少个worker进程才好呢?这实际 上与业务需求有关。
    每个worker进程都是单线程的进程,它们会调用各个模块以实现多种多样的功能。如果 这些模块确认不会出现阻塞式的调用,那么,有多少CPU内核就应该配置多少个进程;反 之,如果有可能出现阻塞式调用,那么需要配置稍多一些的worker进程。
    多worker进程可以充分利用多核系统架构,但若worker进程的数量多于CPU内核数,那 么会增大进程间切换带来的消耗(Linux是抢占式内核)。一般情况下,用户要配置与CPU内 核数相等的worker进程,并且使用worker_cpu_affinity配置来绑定CPU内核。
  • 绑定Nginx worker进程到指定的CPU内核
    语法: worker_cpu_affinity cpumask[cpumask…]
    为什么要绑定worker进程到指定的CPU内核呢?假定每一个worker进程都是非常繁忙的,如果多个worker进程都在抢同一个CPU,那么这就会出现同步问题。反之,如果每一个 worker进程都独享一个CPU,就在内核的调度策略上实现了完全的并发。
    例如:
worker_processes 4;
worker_cpu_affinity 1000 0100 0010 0001;

注意 worker_cpu_affinity配置仅对Linux操作系统有效。Linux操作系统使用 sched_setaffinity()系统调用实现这个功能。

  • SSL硬件加速
    语法: ssl_engine device;
    如果服务器上有SSL硬件加速设备,那么就可以进行配置以加快SSL协议的处理速度。 用户可以使用OpenSSL提供的命令来查看是否有SSL硬件加速设备:
openssl engine -t
  • 系统调用gettimeofday的执行频率
    语法: timer_resolution t;
    默认情况下,每次内核的事件调用(如epoll、select、poll、kqueue等)返回时,都会执 行一次gettimeofday,实现用内核的时钟来更新Nginx中的缓存时钟。
  • Nginx worker进程优先级设置
    语法: worker_priority nice;
    默认: worker_priority 0;
    该配置项用于设置Nginx worker进程的nice优先级。

event 事件类配置项

  • 是否打开accept锁
    语法: accept_mutex[on|off]
    默认: accept_mutext on;
    当一个新连接到达时,如果激活了accept_mutex,那么多个Worker将以串行方式来处理,其中有一个Worker会被唤醒,其他的Worker继续保持休眠状态;如果没有激活accept_mutex,那么所有的Worker都会被唤醒,不过只有一个Worker能获取新连接,其它的Worker会重新进入休眠状态,这就是「惊群问题」
  • lock文件的路径
    语法: lock_file path/file;
    默认: lock_file logs/nginx.lock;
    accept锁可能需要这个lock文件,如果accept锁关闭,lock_file配置完全不生效。
  • 使用accept锁后到真正建立连接之间的延迟时间
    语法: accept_mutex_delay Nms;
    默认: accept_mutex_delay 500ms;
  • 批量建立新连接
    语法: multi_accept[on|off];
    默认: multi_accept off;
    当事件模型通知有新连接时,尽可能地对本次调度中客户端发起的所有TCP请求都建立 连接。
  • 选择事件模型
    语法: use[kqueue|rtsig|epoll|/dev/poll|select|poll|eventport];
    默认: Nginx会自动使用最适合的事件模型。
    对于Linux操作系统来说,可供选择的事件驱动模型有poll、select、epoll三种。epoll当 然是性能最高的一种,在9.6节会解释epoll为什么可以处理大并发连接。
  • 每个worker的最大连接数
    语法: worker_connections number;
    定义每个worker进程可以同时处理的最大连接数。

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

静态Web服务器的主要功能由ngx_http_core_module模块(HTTP框架的主要成员)实现, 当然,一个完整的静态Web服务器还有许多功能是由其他的HTTP模块实现的。
所有的HTTP配置项都必须直属于http块、server块、location块、upstream块或if块等 (HTTP配置项自然必须全部在http{}块之内,这里的“直属于”是指配置项直接所属的大括号 对应的配置块),同时,在描述每个配置项的功能时,会说明它可以在上述的哪个块中存 在,因为有些配置项可以任意地出现在某一个块中,而有些配置项只能出现在特定的块中。
Nginx为配置一个完整的静态Web服务器提供了非常多的功能,下面会把这些配置项分为以下8类进行详述:虚拟主机与请求的分发、文件路径的定义、内存及磁盘资源的分配、网络连接的设置、MIME类型的设置、对客户端请求的限制、文件操作的优化、对客户端请求的特殊处理。

虚拟主机与请求的分发

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

  • 监听端口
    语法: listen port
    默认 80
    配置块: 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协议。

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

  • 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设置了每个散列桶占用的内存大小。

  • 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的冲突率可能增高。

  • 重定向主机名称的处理
    语法: server_name_in_redirect on|off;
    默认: server_name_in_redirect on;
    配置块: http、server或者location
    该配置需要配合server_name使用。在使用on打开时,表示在重定向请求时会使用 server_name里配置的第一个主机名代替原先请求中的Host头部,而使用off关闭时,表示在重 定向请求时使用请求本身的Host头部。

  • location
    语法: location[=||*|^~|@]/uri/{…}
    配置块: server
    location会尝试根据用户请求中的URI来匹配上面的/uri表达式,如果可以匹配,就选择 location{}块中的配置来处理用户请求。当然,匹配方式是多样的。
    location的匹配规则

  • 表示把URI作为字符串,以便与参数中的uri做完全匹配。

  • ~表示匹配URI时是字母大小写敏感的

  • ~*表示匹配URI时忽略字母大小写问题

  • ^~表示匹配URI时只需要其前半部分与uri参数匹配即可

  • @表示仅用于Nginx服务内部请求之间的重定向,带有@的location不直接处理用户请求
    location是有顺序的,当一个请求有可能匹配多个location时,实际上这个请求会 被第一个location处理。
    所有的匹配方式中,都只能表达为“如果匹配…则…”。如果需要表达“如果不匹配… 则…”,就很难直接做到。有一种解决方法是在最后一个location中使用/作为参数,它会匹配所有的HTTP请求,这样就可以表示如果不能匹配前面的所有location,则由“/”这个location处理。

文件路径的定义

  1. 以root方式设置资源路径
    语法: root path;
    默认: root html;
    配置块: http、server、location、if
  2. 以alias方式设置资源路径
    语法: alias path;
    配置块: location
    alias也是用来设置文件资源路径的,它与root的不同点主要在于如何解读紧跟location后 面的uri参数,这将会致使alias与root以不同的方式将用户请求映射到真正的磁盘文件上。
  3. 访问首页
    语法: index file…;
    默认: index index.html;
    配置块: http、server、location
  4. 根据HTTP返回码重定向页面
    语法: error_page code[code…][=|=answer-code]uri|@named_location
    配置块: http、server、location、if
  5. 是否允许递归使用error_page
    语法: recursive_error_pages[on|off];
    默认: recursive_error_pages off;
    配置块: http、server、location
    确定是否允许递归地定义error_page
  6. try_files
    语法: try_files path1[path2]uri;
    配置块: server、location
    try_files后要跟若干路径,如path1 path2…,而且最后必须要有uri参数,意义如下:尝试 按照顺序访问每一个path,如果可以有效地读取,就直接向用户返回这个path对应的文件结 束请求,否则继续向下访问。如果所有的path都找不到有效的文件,就重定向到最后的参数 uri上。因此,最后这个参数uri必须存在,而且它应该是可以有效重定向的。

内存及磁盘资源的分配

  1. HTTP包体只存储到磁盘文件中
    语法: client_body_in_file_only on|clean|off;
    默认: client_body_in_file_only off;
    配置块: http、server、location
    当值为非off时,用户请求中的HTTP包体一律存储到磁盘文件中,即使只有0字节也会存 储为文件。当请求结束时,如果配置为on,则这个文件不会被删除(该配置一般用于调试、 定位问题),但如果配置为clean,则会删除该文件。
  2. HTTP包体尽量写入到一个内存buffer中
    语法: client_body_in_single_buffer on|off;
    默认: client_body_in_single_buffer off;
    配置块: http、server、location
    用户请求中的HTTP包体一律存储到内存buffer中。当然,如果HTTP包体的大小超过了 下面client_body_buffer_size设置的值,包体还是会写入到磁盘文件中。
  3. 存储HTTP头部的内存buffer大小
    语法: client_header_buffer_size size;
    默认: client_header_buffer_size 1k;
    配置块: http、server
  4. 存储超大HTTP头部的内存buffer大小
    语法: large_client_header_buffers number size;
    默认: large_client_header_buffers 48k;
    配置块: http、server
  5. 存储HTTP包体的内存buffer大小
    语法: client_body_buffer_size size;
    默认: client_body_buffer_size 8k/16k;
    配置块: http、server、location
  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
  8. request_pool_size
    语法: request_pool_size size;
    默认: request_pool_size 4k;
    配置块: http、server

网络连接的设置

  1. 读取HTTP头部的超时时间
    语法: client_header_timeout time(默认单位:秒);
    默认: client_header_timeout 60;
    配置块: http、server、location
  2. 读取HTTP包体的超时时间
    语法: 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包来直接重置连接。这个选项打开后,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是中间值,一般情况下在关闭连接前都会处理连接上的用户发送的数据,除了 有些情况下在业务上认定这之后的数据是不必要的。
  6. lingering_time
    语法: lingering_time time;
    默认: lingering_time 30s;
    配置块: http、server、location
  7. lingering_timeout
    语法: lingering_timeout time;
    默认: lingering_timeout 5s;
    配置块: http、server、location
  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
  10. 一个keepalive长连接上允许承载的请求最大数
    语法: keepalive_requests n;
    默认: keepalive_requests 100;
    配置块: http、server、location
  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
  2. 默认MIME type
    语法: default_type MIME-type;
    默认: default_type text/plain;
    配置块: http、server、location
  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
    Nginx通过limit_except后面指定的方法名来限制用户请求。方法名可取值包括:GET、 HEAD、POST、PUT、DELETE、MKCOL、COPY、MOVE、OPTIONS、PROPFIND、 PROPPATCH、LOCK、UNLOCK或者PATCH。
  2. HTTP请求包体的最大值
    语法: client_max_body_size size;
    默认: client_max_body_size 1m;
    配置块: http、server、location
    浏览器在发送含有较大HTTP包体的请求时,其头部会有一个Content-Length字段, client_max_body_size是用来限制Content-Length所示值的大小的。因此,这个限制包体的配置 非常有用处,因为不用等Nginx接收完所有的HTTP包体——这有可能消耗很长时间——就可以告诉用户请求过大不被接受。
  3. 对请求的限速
    语法: limit_rate speed;
    默认: limit_rate 0;
    配置块: http、server、location、if
    此配置是对客户端请求限制每秒传输的字节数。speed可以使用2.2.4节中提到的多种单位,默认参数为0,表示不限速。
  4. limit_rate_after
    语法: limit_rate_after time;
    默认: limit_rate_after 1m;
    配置块: http、server、location、if
    此配置表示Nginx向客户端发送的响应长度超过limit_rate_after后才开始限速。

文件操作的优化

  1. sendfile系统调用
    语法: sendfile on|off;
    默认: sendfile off;
    配置块: http、server、location
    可以启用Linux上的sendfile系统调用来发送文件,它减少了内核态与用户态之间的两次 内存复制,这样就会从磁盘中读取文件后直接在内核态发送到网卡设备,提高了发送文件的 效率。
  2. AIO系统调用
    语法: aio on|off;
    默认: aio off;
    配置块: http、server、location
    此配置项表示是否在FreeBSD或Linux系统上启用内核级别的异步文件I/O功能。注意, 它与sendfile功能是互斥的。
  3. directio
    语法: directio size|off;
    默认: directio off;
    配置块: http、server、location
    此配置项在FreeBSD和Linux系统上使用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指定的时间段内没有被访问过的元素将会被淘汰。默认时间为
    ·off:关闭缓存功能。
  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
  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 Not Modified,浏览器收到后会直接读取自己的本地缓存。
    ·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
  6. DNS解析地址
    语法: resolver address…;
    配置块: http、server、location
    设置DNS名字解析服务器的地址
  7. DNS解析的超时时间
    语法: resolver_timeout time;
    默认: resolver_timeout 30s;
    配置块: http、server、location
    此配置项表示DNS解析的超时时间。
  8. 返回错误页面时是否在Server中注明Nginx版本
    语法: server_tokens on|off;
    默认: server_tokens on;
    配置块: http、server、location

用HTTP proxy module配置一个反向代理服务器

反向代理(reverse proxy)方式是指用代理服务器来接受Internet上的连接请求,然后将 请求转发给内部网络中的上游服务器,并将从上游服务器上得到的结果返回给Internet上请求 连接的客户端,此时代理服务器对外的表现就是一个Web服务器。充当反向代理服务器也是 Nginx的一种常见用法(反向代理服务器必须能够处理大量并发请求)。
由于Nginx具有“强悍”的高并发高负载能力,因此一般会作为前端的服务器直接向客户端提供静态文件服务。但也有一些复杂、多变的业务不适合放到Nginx服务器上,这时会用 Apache、Tomcat等服务器来处理。于是,Nginx通常会被配置为既是静态Web服务器也是反向 代理服务器(如下图所示),不适合Nginx处理的请求就会直接转发到上游服务器中处理。
在这里插入图片描述
与Squid等其他反向代理服务器相比,Nginx的反向代理功能有自己的特点,如下图所示。
在这里插入图片描述

当客户端发来HTTP请求时,Nginx并不会立刻转发到上游服务器,而是先把用户的请求 (包括HTTP包体)完整地接收到Nginx所在服务器的硬盘或者内存中,然后再向上游服务器 发起连接,把缓存的客户端请求转发到上游服务器。而Squid等代理服务器则采用一边接收客户端请求,一边转发到上游服务器的方式。

Nginx的这种工作方式有什么优缺点呢?很明显,缺点是延长了一个请求的处理时间, 并增加了用于缓存请求内容的内存和磁盘空间。而优点则是降低了上游服务器的负载,尽量 把压力放在Nginx服务器上。

Nginx的这种工作方式为什么会降低上游服务器的负载呢?通常,客户端与代理服务器之间的网络环境会比较复杂,多半是走公网,网速平均下来可能较慢,因此,一个请求可能要持续很久才能完成。而代理服务器与上游服务器之间一般是走内网,或者有专线连接,传输速度较快。Squid等反向代理服务器在与客户端建立连接且还没有开始接收HTTP包体时,就已经向上游服务器建立了连接,这样的话如果客户端传输一个大文件,在刚开始代理服务器就与上游服务器建立起了连接,并且上游服务器始终要保持这个链接,这对上游服务器的并发能力有很大的挑战。

而Nginx它在接收到完整的客户端请求(如1GB的文件)后,才会与上游服务器建立连接转发请求,由于是内网,所以这个转发过程会执行得很快。这样,一个客户端请求占用上游服务器的连接时间就会非常短,也就是说,Nginx的这种反向代理方案主要是为了降低上游服务器的并发压力。

负载均衡的基本配置

作为代理服务器,一般都需要向上游服务器的集群转发请求。这里的负载均衡是指选择一种策略,尽量把请求平均地分布到每一台上游服务器上。

  1. upstream块
    语法: upstream name{…}
    配置块: http
    upstream块定义了一个上游服务器的集群,便于反向代理中的proxy_pass使用。
    例如:
upstream backend {
	server backend1.example.com; server backend2.example.com;
	server backend3.example.com; }
server { 
	location / {
  		proxy_pass http://backend;
  	} 
}
  1. server
    语法: server name[parameters];
    配置块: upstream
    server配置项指定了一台上游服务器的名字,这个名字可以是域名、IP地址端口、UNIX 句柄等,在其后还可以跟以下参数:
    ·weight=number:设置向这台上游服务器转发的权重,默认为1。
    ·max_fails=number:该选项与fail_timeout配合使用,指在fail_timeout时间段内,如果向当前的上游服务器转发失败次数超过number,则认为在当前的fail_timeout时间段内这台上游 服务器不可用。max_fails默认为1,如果设置为0,则表示不检查失败次数。
    ·fail_timeout=time::ail_timeout表示该时间段内转发失败多少次后就认为上游服务器暂 时不可用,用于优化反向代理功能。它与向上游服务器建立连接的超时时间、读取上游服务 器的响应超时时间等完全无关。fail_timeout默认为10秒。
    ·down:表示所在的上游服务器永久下线,只在使用ip_hash配置项时才有用。
    ·backup:在使用ip_hash配置项时它是无效的。它表示所在的上游服务器只是备份服务 器,只有在所有的非备份上游服务器都失效后,才会向所在的上游服务器转发请求。
    例如:

upstream backend {
	server backend1.example.com weight=5;
	server 127.0.0.1:8080 max_fails=3 fail_timeout=30s; server unix:/tmp/backend3;
}
  1. ip_hash
    语法: ip_hash;
    配置块: upstream
    在有些场景下,我们可能会希望来自某一个用户的请求始终落到固定的一台上游服务器中。ip_hash与weight(权重)配置不可同时使用。如果upstream集群中有一台上游服务器暂 时不可用,不能直接删除该配置,而是要down参数标识,确保转发策略的一贯性。
  2. 记录日志时支持的变量
    如果需要将负载均衡时的一些信息记录到access_log日志中,那么在定义日志格式时可以使用负载均衡功能提供的变量。
    在这里插入图片描述
    例如,可以在定义access_log访问日志格式时使用上表的变量。
log_format timing '$remote_addr - $remote_user [$time_local] $request ' 'upstream_response_time $upstream_response_time '
'msec $msec request_time $request_time';
log_format up_head '$remote_addr - $remote_user [$time_local] $request ' 'upstream_http_content_type $upstream_http_content_type';

反向代理的基本配置

  1. proxy_pass
    语法:proxy_pass URL;
    配置块:location、if
    此配置项将当前请求反向代理到URL参数指定的服务器上,URL可以是主机名或IP地址 加端口的形式。
    例如:
proxy_pass http://localhost:8000/uri/

也可以是UNIX句柄:

proxy_pass http://unix:/path/to/backend.socket:/uri/

也可以把HTTP转换成更安全的HTTPS,例如:

proxy_pass https://192.168.0.1

默认情况下反向代理是不会转发请求中的Host头部的。如果需要转发,那么必须加上配置:

proxy_set_header Host $host;
  1. proxy_method
    语法:proxy_method method;
    配置块:http、server、location
    此配置项表示转发时的协议方法名。例如设置为:
proxy_method POST;
  1. proxy_hide_header
    语法:proxy_hide_header the_header;
    配置块:http、server、location
    Nginx会将上游服务器的响应转发给客户端,但默认不会转发以下HTTP头部字段: Date、Server、X-Pad和X-Accel-*。使用proxy_hide_header后可以任意地指定哪些HTTP头部 字段不能被转发。例如:
proxy_hide_header Cache-Control; 
proxy_hide_header MicrosoftOfficeWebServer;
  1. proxy_pass_header
    语法:proxy_pass_header the_header;
    配置块:http、server、location
    与proxy_hide_header功能相反,proxy_pass_header会将原来禁止转发的header设置为允许 转发。例如:
proxy_pass_header X-Accel-Redirect;
  1. proxy_pass_request_body
    语法:proxy_pass_request_body on|off;
    默认:proxy_pass_request_body on;
    配置块: http、server、location
    作用为确定是否向上游服务器发送HTTP包体部分。
  2. proxy_pass_request_headers
    语法:proxy_pass_request_headers on|off;
    默认:proxy_pass_request_headers on;
    配置块:http、server、location
    作用为确定是否转发HTTP头部
  3. proxy_redirect
    语法:proxy_redirect[default|off|redirect replacement];
    默认:proxy_redirect default;
    配置块:http、server、location
    当上游服务器返回的响应是重定向或刷新请求(如HTTP响应码是301或者302)时, proxy_redirect可以重设HTTP头部的location或refresh字段。
  4. proxy_next_upstream
    语法:proxy_next_upstream[error|timeout|invalid_header|http_500|http_502|http_503|http_504|http_404|off];
    默认:proxy_next_upstream error timeout;
    配置块:http、server、location
    此配置项表示当向一台上游服务器转发请求出现错误时,继续换一台上游服务器处理这个请求。
    上游服务器一旦开始发送应答,Nginx反向代理服务器会立刻把应 答包转发给客户端。因此,一旦Nginx开始向客户端发送响应包,之后的过程中若出现错误 也是不允许换下一台上游服务器继续处理的。这很好理解,这样才可以更好地保证客户端只 收到来自一个上游服务器的应答。proxy_next_upstream的参数用来说明在哪些情况下会继续 选择下一台上游服务器转发请求。
    ·error:当向上游服务器发起连接、发送请求、读取响应时出错。
    ·timeout:发送请求或读取响应时发生超时。
    ·invalid_header:上游服务器发送的响应是不合法的。
    ·http_500:上游服务器返回的HTTP响应码是500。
    ·http_502:上游服务器返回的HTTP响应码是502。
    ·http_503:上游服务器返回的HTTP响应码是503。
    ·http_504:上游服务器返回的HTTP响应码是504。
    ·http_404:上游服务器返回的HTTP响应码是404。
    ·off:关闭proxy_next_upstream功能—出错就选择另一台上游服务器再次转发。