前言
该文章介绍 nginx ,并未使用 nginx 来搭建 web服务器,反向代理服务器,负载均衡服务器等…
会在接下来几篇文章重点记录 nginx 的实践。
正文
yum安装nginx
1.更新nginx官方yum源
vim /etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
2.yum安装nginx软件
yum install -y nginx
3.启动nginx服务,设置开机自启动
systemctl start nginx
systemctl enable nginx
nginx 应用
nginx (engine x)是一个可以作为HTTP WEB服务器、反向代理服务器、邮件代理服务器和一个通用的TCP / UDP代理服务器(1.9.0版本后)的多功能架构组件,同时也可以提供一定的缓存服务功能。
nginx应用比较多的场景是WEB服务器和反向代理服务器,这两个场景的相关配置后面的文章我们会分别操作配置,这里先来认识下
Web服务器
**WEB服务器:**这是应用比较多的场景,配置虚拟主机提供HTTP WEB服务。可以先通过动态/静态内容分离,而后为静态内容(html/css/js/图片等)提供HTTP访问功能;而动态内容可以整合代理模块,代理给上游服务器,来支持对外部程序的直接调用或者解析,如FastCGI支持PHP。
反向代理服务器
**反向代理服务器:**这是应用非常多的场景,为后端服务器代理。接收客户端请求,根据负载均衡策略转发给后端多个上游服务器处理;然后再等待后端服务器返回请求响应,接收到后再返回给请求的客户端。
什么是代理?
代理其实就是一个中介,A和B本来可以直连,中间插入一个C,C就是中介。
刚开始的时候,代理多数是帮助内网client访问外网server用的
后来出现了反向代理,"反向"这个词在这儿的意思其实是指方向相反,即代理将来自外网客户端的请求转发到内网服务器,从外到内
正向代理
反向代理
反向代理(Reverse Proxy)实际运行方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个服务器
反向代理的作用:
- 保证内网的安全,阻止web攻击,大型网站,通常将反向代理作为公网访问地址,Web服务器是内网
- 负载均衡,通过反向代理服务器来优化网站的负载
nginx 基本架构
1、一个master进程生成多个worker子进程(每个进程只有一个线程),一个worker响应多个用户请求;
2、非阻塞、IO复用、事件驱动:select,poll, epoll, kqueue,/dev/poll;
epoll模型:
宿舍管理员: 找人,查看人员登记信息
幼儿园阿姨: 小朋友上厕所, 都站在教室的某个位置
select模型:
宿舍管理员: 找人,一个一个屋子去问, --线性轮询
幼儿园阿姨: 小朋友上厕所, 一个一个小朋友去询问
3、支持sendfile,sendfile64;
4、支持文件AIO(异步I/O);
5、支持mmap;
6、灵活的文件配置;
7、占用内存小:10,000个非活动HTTP保持连接占用大约2.5M内存。
nginx功能特性
基本功能
实现与服务静态文件(静态资源的web服务器),能缓存打开的文件描述符;
反向代理服务器,缓存、负载均衡、健康状态检测;
支持FastCGI;
模块化机制,非DSO机制,支持多种过滤器gzip,SSI和图像的模块完成图形大小调整等;
支持SSL(HTTPS 就是 利用 SSL 来加密的);
什么是负载均衡
负载均衡是高可用网络基础架构的关键组件,通常用于将工作负载分布到多个服务器来提高网站、应用、数据库或其他服务的性能和可靠性。
一个没有负载均衡的 web 架构类似下面这样:
在这里用户是直连到 web 服务器,如果这个服务器宕机了,那么用户自然也就没办法访问了。另外,如果同时有很多用户试图访问服务器,超过了其能处理的极限,就会出现加载速度缓慢或根本无法连接的情况。
而通过在后端引入一个负载均衡器和至少一个额外的 web 服务器,可以缓解这个故障。通常情况下,所有的后端服务器会保证提供相同的内容,以便用户无论哪个服务器响应,都能收到一致的内容。
从图里可以看到,用户访问负载均衡器,再由负载均衡器将请求转发给后端服务器。在这种情况下,单点故障现在转移到负载均衡器上了。这里又可以通过引入第二个负载均衡器来缓解。
负载均衡器可以处理什么样的请求?
负载均衡器的管理员能主要为下面四种主要类型的请求设置转发规则:
- HTTP
- HTTPS
- TCP
- UDP
负载均衡器如何选择要转发的后端服务器?
负载均衡器一般根据两个因素来决定要将请求转发到哪个服务器。首先,确保所选择的服务器能够对请求做出响应,然后根据预先配置的规则从健康服务器池(healthy pool)中进行选择。
因为,负载均衡器应当只选择能正常做出响应的后端服务器,因此就需要有一种判断后端服务器是否「健康」的方法。为了监视后台服务器的运行状况,运行状态检查服务会定期尝试使用转发规则定义的协议和端口去连接后端服务器。如果,服务器无法通过健康检查,就会从池中剔除,保证流量不会被转发到该服务器,直到其再次通过健康检查为止。
负载均衡算法
负载均衡算法决定了后端的哪些健康服务器会被选中。几个常用的算法:
- Round Robin(轮询):为第一个请求选择列表中的第一个服务器,然后按顺序向下移动列表直到结尾,然后循环。
- Least Connections(最小连接):优先选择连接数最少的服务器,在普遍会话较长的情况下推荐使用。
- Source:根据请求源的 IP 的散列(hash)来选择要转发的服务器。这种方式可以一定程度上保证特定用户能连接到相同的服务器。
如果你的应用需要处理状态而要求用户能连接到和之前相同的服务器。可以通过 Source 算法基于客户端的 IP 信息创建关联,或者使用粘性会话(sticky sessions)。
最后,想要解决负载均衡器的单点故障问题,可以将第二个负载均衡器连接到第一个上,从而形成一个集群。
当主负载均衡器发生了故障,就需要将用户请求转到第二个负载均衡器。因为 DNS 更改通常会较长的时间才能生效,因此需要能灵活解决 IP 地址重新映射的方法,比如浮动 IP(floating IP)。这样域名可以保持和相同的 IP 相关联,而 IP 本身则能在服务器之间移动。
一个使用浮动 IP 的负载均衡架构示意图:
扩展功能
基于名称和IP做虚拟主机;
支持keeplive;
支持平滑配置更新或程序版本升级;
定制访问日志,支持使用日志缓存以提高性能;
支持URL rewrite;
支持路径别名;
支持基于IP及用户的认证;
支持速率限制,并发数限制等;
什么是 keeplive
首先,我们要明确我们谈的是TCP的 KeepAlive
还是HTTP的 Keep-Alive
。TCP的KeepAlive
和HTTP的Keep-Alive
是完全不同的概念,不能混为一谈。实际上HTTP的KeepAlive写法是
Keep-Alive,跟TCP的
KeepAlive`写法上也有不同。
- TCP的
keepalive
是侧重在保持客户端和服务端的连接,一方会不定期发送心跳包给另一方,当一方端掉的时候,没有断掉的定时发送几次心跳包,如果间隔发送几次,对方都返回的是RST,而不是ACK,那么就释放当前链接。设想一下,如果tcp层没有keepalive
的机制,一旦一方断开连接却没有发送FIN给另外一方的话,那么另外一方会一直以为这个连接还是存活的,几天,几月。那么这对服务器资源的影响是很大的。 - HTTP的
keep-alive
一般我们都会带上中间的横杠,普通的http连接是客户端连接上服务端,然后结束请求后,由客户端或者服务端进行http连接的关闭。下次再发送请求的时候,客户端再发起一个连接,传送数据,关闭连接。这么个流程反复。但是一旦客户端发送connection:keep-alive
头给服务端,且服务端也接受这个keep-alive
的话,两边对上暗号,这个连接就可以复用了,一个http处理完之后,另外一个http数据直接从这个连接走了。减少新建和断开TCP连接的消耗。
二者的作用简单来说:
HTTP协议的Keep-Alive意图在于短时间内连接复用,希望可以短时间内在同一个连接上进行多次请求/响应。
TCP的KeepAlive机制意图在于保活、心跳,检测连接错误。当一个TCP连接两端长时间没有数据传输时(通常默认配置是2小时),发送keepalive探针,探测链接是否存活。
总之,记住HTTP的Keep-Alive和TCP的KeepAlive不是一回事。
tcp的keepalive是在ESTABLISH状态的时候,双方如何检测连接的可用行。而http的keep-alive说的是如何避免进行重复的TCP三次握手和四次挥手的环节。
nginx并发模型
如前图,一个master进程生成多个worker子进程(每个进程只有一个线程),一个worker响应多个用户请求。如果单进程启动:仅有一个进程,既充当master进程的角色,也充当worker进程的角色。
master进程
充当整个进程组与用户的交互接口(接收来自外界的信号,向各worker进程发送信号),同时监控worker进程的运行状态。
它不需要处理网络事件,不负责业务的执行,只会通过管理worker进程来实现重启服务、平滑升级、更换日志文件、配置文件实时生效等功能。
worker进程
主要任务是处理基本的网络事件,完成具体的任务逻辑。多个worker进程之间是对等的,互相独立的。
worker进程主要关注点是与客户端或后端服务器(此时nginx作为中间代理)之间的数据可读/可写等I/O交互事件,所以工作进程的阻塞点是在像select()、epoll_wait()等这样的I/O多路复用函数调用处,以等待发生数据可读/写事件。当然也可能被新收到的进程信号中断
worker进程个数:
如果负载以CPU密集型应用为主,一般会设置与机器cpu核数一致或少一个(用来处理用户等其他任务);
如果负载以IO密集型为主,如响应大量内容给客户端,则worker数应该为CPU个数的1.5或2倍。
因为更多的worker数,只会导致进程来竞争cpu资源了,从而带来不必要的上下文切换。而且,nginx为了更好的利用多核特性,具有cpu绑定选项,我们可以将某一个进程绑定在某一个核上,这样就不会因为进程的切换带来cache的失效。
更具体的可以根据公式:Nthread = NcpuUcpu(1+W/C),Ncpu是cpu的个数,Ucpu是cpu的使用率,W为等待时间,C为计算时间。这时需要通过监控工具来获取相应数据来计算。
最后,再以监控工具数据为准进行微调。
并发处理
A、在master进程里面,先创建socket,并bind、listen在80端口(所以master进程需要root权限);
B、然后再fork出多个worker进程,这样每个worker进程都可以去accept这个socket(会产生惊群问题), 或者使用锁机制,让抢到锁的一个worker进程去accept这个socket,注意这里一般使用select/poll/epoll机制来解决accept阻塞问题;
C、当一个新连接进来后,而只有抢到锁的一个进程可以accept这个连接进行处理(也是放入epoll中);
D、抢到锁的worker进程accept到新连接后,会立即释放锁;然后所有worker进程再次参与抢锁,这样就回到了第二步,进行循环处理并发连接;
惊群问题
A、产生原因:像上面第二步,多个worker进程等待同一个socket的连接事件,当这个事件发生时,这些进程被同时唤醒,就是惊群。
注意,在linux2.6内核上,accept系统调用已经不存在惊群,但用epoll机制来解决accept阻塞问题,epoll_wait会有惊群问题(新增 EPOLLEXCLUSIVE 选项解决了)。
B、导致后果:许多worker进程被内核重新调度唤醒,只有一个进程可以accept这个连接进行处理,其他余者皆失败,导致性能浪费。
C、nginx解决方案:使用锁机制,让抢到锁的一个worker进程去accept(epoll_wait)这个socket;如果操作系统支持原子整型,才会使用共享内存实现原子上锁,否则使用文件上锁。
Nginx配置说明
配置文件区域说明
nginx主要配置文件nginx.conf,里面主要包括以下几个配置区域,如下表:
/etc/nginx/nginx.conf
配置区域 | 说明 |
main块 | 配置影响nginx全局的指令。一般有运行nginx服务器的用户组,nginx进程pid存放路径,日志存放路径,配置文件引入,允许生成worker process数等。 |
events块 | 配置影响nginx服务器或与用户的网络连接。有每个进程的最大连接数,选取哪种事件驱动模型处理连接请求,是否允许同时接受多个网路连接,开启多个网络连接序列化等。 |
http块 | 可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。如文件引入,mime-type定义,日志自定义,是否使用sendfile传输文件,连接超时时间,单连接请求数等。 |
upstream块 | 配置HTTP负载均衡器分配流量到几个应用程序服务器。 |
server块 | 配置虚拟主机的相关参数,一个http中可以有多个server。 |
location块 | 配置请求的路由,以及允许根据用户请求的URI来匹配指定的各location以进行访问配置;匹配到时,将被location块中的配置所处理。 |
nginx文件结构如下:
... #main全局块
events { #events块
...
}
http #http块
{
... #http全局块
upstream … # upstream负载均衡块
{
…
}
server #server块
{
... #server全局块
location [PATTERN] #location块
{
...
}
location [PATTERN]
{
...
}
}
server
{
...
}
... #http全局块
}
Nginx核心功能配置
nginx核心功能配置主要是main和events的顶层全局配置,都是配置nginx核心模块(ngx_core_module),管理服务器级别的行为。下表包含是大部分常用的配置选项,更多配置请参考官方文档:http://nginx.org/en/docs/ngx_core_module.html
基本配置
配置选项 | 上下文 | 语法 | 默认值 | 功能描述 |
user | main | user username [groupname] | nobody | 以那个用户身份运行,以在configure指定的用户为准 |
pid | main | pid /path/to/pid_filename | nginx.pid | 指定nginx的pid文件 |
worker_rlimit_nofile | main | 受linux内核文件描述符数量限制 | 指定一个worker进程所能够打开的句柄数。因为Linux对每个进程所能打开的文件描述数量是有限制的,默认一般是1024个,可通过ulimit -n FILECNT或/etc/securit/limits.conf配置修改linux默认能打开的文件句柄数限制。建议值为:系统最大数量/进程数。但进程间工作量并不是平均分配的,所以可以设置在大一些。推荐值为:655350。 |
优化性能相关配置
配置选项 | 上下文 | 语法 | 默认值 | 功能描述 |
worker_procrsses | main | worker_processes number | auto; | 1 | work进程的个数.如果负载以CPU密集型应用为主,一般会设置与机器cpu核数一致或少一个(用来处理用户等其他任务),如果负载以IO密集型为主,如响应大量内容给客户端,则worker数应该为CPU个数的1.5或2倍。因为更多的worker数,只会导致进程来竞争cpu资源了,从而带来不必要的上下文切换。而且,nginx为了更好的利用多核特性,具有cpu绑定选项,我们可以将某一个进程绑定在某一个核上,这样就不会因为进程的切换带来cache的失效。 |
worker_cpu_affinity | main | worker_cpu_affinity cpumask …; | 无,不绑定 | 将工作进程绑定到特定的CPU上,减少CPU在进程之间切换的开销。用二进制bit位表示进程绑定在哪个CPU内核。如4工作进程4内核:worker_processes 4;worker_cpu_affinity 0001 0010 0100 1000;2工作进程4内核:worker_processes 2;worker_cpu_affinity 0101 1010; |
worker_priority | main | worker_priority number; | 0 | 工作进程调度优先级,-20到19之间的值,值越小越优先调用。如果系统同时运行多个任务,你可能需要提高nginx的工作进程的优先级 |
事件相关配置
配置选项 | 上下文 | 语法 | 默认值 | 功能描述 |
worker_commections | events | worker_connections number; | 512 | 每个worker能够并发响应的最大请求数。系统每处理一个请求就要消耗一个套接字文件,如果为代理服务器的话,worker_rlimit_nofile=worker_commections*2 |
use | events | use method; | 无,自动选择 | 指定使用哪种模型(select/poll/epoll),建议让nginx自动选择,linux内核2.6以上一般能使用epoll,提高性能。 |
accept_mutex | events | accept_mutex on | off; | Off(1.11.3版本前默认on) |
accept_mutex_delay | events | accept_mutex_delay time; | 500ms | 使用accept锁以后,只有一个worker能取得锁,一个worker进程为取得accept锁的等待时长,即用户建立等待的时间,如果某worker进程在某次试图取得锁时失败了,至少要等待#ms才能在一次请求锁 |
multi_accept | events | multi_accept on | off; | off |
调试,定位问题配置
配置选项 | 上下文 | 语法 | 默认值 | 功能描述 |
daemon | main | daemon on | off; | on | nginx是否以守护进程运行,是否让nignx运行于后台;调试时应该为off,使得所有信息直接输出在控制台 |
master_process | main | master_process on | off; | on | 是否以master/worker模式运行nginx,默认为on,调试时可以设置为off以方便追踪 |
error_log | main, http, mail, stream, server, location | error_log file [level]; | error_log logs/error.log error; | 配置错误日志文件的路径和日志级别。日志级别有debug, info, notice, warn, error, crit, alert和emerg几种。调试时可以使用debug级别,但要求在编译时必须使用–with-debug启用debug功能,默认通常为error级别. |
Nginx HTTP核心配置
http功能核心配置主要是http块、server块和location块的配置,包括HTTP核心模块(ngx_http_core_module)和一些扩展模块(如ngx_stream_ssl_module),提供管理WEB服务器级别的行为。
必须使用虚拟机来配置站点,每个虚拟主机使用一个server{}段来配置,非虚拟主机的配置和公共选项,需要定义在server之外,http之内
下表包含是大部分常用的配置选项,更多配置请参考官方文档:http://nginx.org/en/docs/
基本配置
配置选项 | 上下文 | 语法 | 默认值 | 功能描述 |
http | main | http { … } | 无 | 提供HTTP服务器配置上下文 |
server | http | server { … } | 无 | HTTP服务器的核心配置,定义一个虚拟主机:nginx支持使用基于主机名或IP的虚拟主机 |
listen | server | listen address[:port] listen prot listen unix:socket | listen *:80 | 配置虚拟主机监听的IP地址和端口,默认监听本机IP地址和80或8000端口。如果只设置了IP没设端口,默认使用80端口。如果只设置了端口,没设置IP默认使用本机IP。后面可以指定一些参数:default_server:定义此server为http中默认的server;如果所有的server中任何一个listen使用此参数,那么第一个server即为默认server;rcvbuf=SIZE:接收缓存大小;sndbuf=SIZE: 发送缓存大小;ssl:https server:必须以ssl连接; |
server_name | server | server_name name …; | “” | 配置虚拟主机的域名,可以指定多个,用空格分隔。默认为空。名称可以使用通配符和正则表达式(通常以~开头):当nginx收到一个请求时,会取出其首部的server的值,而后跟众server_name进行比较:比较方式(1) 先做精确匹配,如www.tjiyu.com(2) 左侧通配符匹配,如tjiyu.com(3) 右侧通配符匹配,如www.(4) 正则表达式匹配 |
server_name_hash_bucket_size | server | server_names_hash_bucket_size size; | 32|64|128 | 为了实现快速主机查找,nginx使用hash表来保存主机名。默认值取决于处理器缓存线的大小。 |
location | server, location | location [ = | ~ | ~* | ^~ ] uri { … }location @name { … } | 无 | 允许根据用户请求的URI来匹配指定的各location以进行访问配置;匹配到时,将被location块中的配置所处理。=:精确匹配;~:正则表达式模式匹配,匹配时区分字符大小写;~*:正则表达式模式匹配,匹配时忽略字符大小写;^~:只需要前半部分与uri匹配即可,不检查正则表达式;匹配优先级:字符字面量最精确匹配、正则表达式检索(由多个时,由第一个匹配到的所处理),按字符字面量。 |
资源路径定义
配置选项 | 上下文 | 语法 | 默认值 | 功能描述 |
root | http, server, location, if in location | root path; | root html; | 设置web资源路径,用于指定请求的根文档目录,从根开始匹配。如root /html/image/,请求"/tjiyu.gif"对应的文件为"/html/image/tjiyu.gif" |
alias | location | alias path; | 无 | 指定路径别名,只能用于location中,从最后一个/开始匹配。如location /i/ {alias /data/w3/images/;} 请求"/i/top.gif", 实际文件"/data/w3/images/top.gif" |
Index | http, server, location | index file …; | index index.html; | ngx_http_index_module.定义默认页面,可以跟多个值。自左向右匹配。 |
error_page | http, server, location, if in location | http, server, location, if in location | 无 | ngx_http_core_module当对于某个请求发回错误时,如果匹配上了error_page指令中设定的code,则从定向至新的URI中,错误重定向.如 error_page 500 502 503 504 /50x.html也可以改变返回码。如error_page 404 =200 /404.html; |
try_files | server, location | try_files file … uri;try_files file … =code; | 无 | 自左向右尝试读取有path所指定路径,在第一找到即停止并返回,如果所有path均不存在,则返回最后一个uri或者code.如try_files $uri $uri/index.html $uri.html =404; |
网络连接相关配置
配置选项 | 上下文 | 语法 | 默认值 | 功能描述 |
keepalive_timeout | http, server, location | keepalive_timeout timeout [header_timeout]; | 75s | 保持连接的超时时长,默认为75s。降低每个连接的alive时间可在一定程度上提高可响应连接数量,所以一般可适当降低此值 |
keepalive_requests | http, server, location | keepalive_requests number; | 100 | 在一次长连接上允许承载的最大请求数。 |
keepalive_disable | http, server, location | keepalive_disable none | browser …; | msie6(ie6无法长连接) | 对指定的浏览器禁止使用长连接 |
tcp_nodelay | http, server, location | tcp_nodelay on | off; | on | 这里指ngx_http_core_module模块的选项。对keepalive连接是否使用tcp_nodelay选项 |
启动配置,会在数据包达到一定大小后再发送数据。这样会减少网络通信次数,降低阻塞概率,但也会影响响应及时性。比较适合于文件下载这类的大数据通信场景。 | ||||
client_header_timeout | http, server | client_header_timeout time; | 60s | client_header_timeout time; |
client_body_timeout | http, server, location | client_body_timeout time; | 60s | 读取http请求包体的超时时间。 |
send_timeout | http, server, location | send_timeout time; | 60s | 发送响应的超时时长。超时后连接将关闭。 |
对客户端请求的限制配置
配置选项 | 上下文 | 语法 | 默认值 | 功能描述 |
client_max_body_size | http, server, location | client_max_body_size size; | 1m | http请求包体的最大值,常用于限定客户端所能够请求的最大包体,根据请求首部中的Content-Length来检查,以避免无用的传输。 |
limit_except | location | limit_except method … { … } | on | 指定范围之外的其他方法的访问控制。方法有:GET, HEAD, POST, PUT, DELETE, MKCOL, COPY, MOVE, OPTIONS, PROPFIND, PROPPATCH, LOCK, UNLOCK, or PATCH.如只允许GET访问:limit_except GET {allow 192.168.1.0/32;deny all;} |
limit_rate | http, server, location, if in location | limit_rate rate; | 0 | 限制客户端每秒传输的字节数,默认为0,表示没有限制。 |
limit_rate_after | http, server, location, if in location | limit_rate_after size; | 0 | nginx向客户端发送响应报文时,如果时长超过了此处指定的时长,则后续的发送过程开始限速(下载站点常用)。配置上面的limit_rate使用。 |
对客户端请求的特殊处理
配置选项 | 上下文 | 语法 | 默认值 | 功能描述 |
ignore_invalid_headers | http, server | ignore_invalid_headers on | off; | on |
log_not_found | http, server, location | log_not_found on | off; | on | 用户访问的文件不存在时,是否将其记录到错误日志中。 |
resolver | http, server, location | resolver address … [valid=time] [ipv6=on | off]; | 无 |
valid = 30s,整缓存时间设置。在1.1.9版之前,不可能调整缓存时间,而nginx总是缓存答案5分钟的时间。 | ||||
resolver_timeout | http, server, location | resolver_timeout time; | 30s | 指定DNS解析超时时长。 |
文件操作的优化
配置选项 | 上下文 | 语法 | 默认值 | 功能描述 |
sendfile | http, server, location, if in location | sendfile on | off; | off | 是否启用sendfile内核复制模式功能。作为静态服务器可以提高最大的IO访问速度。传统的文件读写采用read和write方式,流程为:硬盘 >> kernel buffer >> user buffer>> kernel socket buffer >>协议栈,采用sendfile文件读写的流程为:硬盘 >> kernel buffer (快速拷贝到kernelsocket buffer) >>协议栈,很明显sendfile这个系统调用减少了内核到用户模式之间的切换和数据拷贝次数,直接从内核缓存的数据拷贝到协议栈,提高了很大的效率。 |
aio | http, server, location | aio on | off | threads[=pool]; | off | 是否启用异步文件IO功能。Linux从内核版本2.6.22开始支持,有必要启用directio,否则读取将阻塞。directio只能用于读取在512字节边界(或XFS为4K)上对齐的块。文件结束未对齐将在阻塞模式下读取。当在Linux上同时启用AIO和sendfile功能时,AIO用于大于或等于directio指令中指定大小的文件,而小于或禁用directio时则用sendfile。location /video/ {sendfile on;aio on;directio 8m;} |
open_file_cache | http, server, location | open_file_cache off;open_file_cache max=N[inactive=time]; | off | 是否打开文件缓存功能。max:用于缓存条目的最大值,允许打开的缓存条目最大数,当满两类以后将根据LRU(最小最少连接数)算法进行置换inactive:某缓存条目在指定时长内没有被访问过时,将自动被删除,即缓存有效期,通常默认为60s。缓存的信息包括:文件句柄、文件大小和上次修改时间;已经打开的目录结构;没有找到或没有访问权限的信息等。建议值:max=655350(和worker_rlimit_nofile参数一致) inactive=20s; |
open_file_cache_errors | http, server, location | open_file_cache_errors on | off; | off | 是否缓存文件找不到或没有权限访问等相关信息。 |
open_file_cache_valid | http, server, location | open_file_cache_valid time; | 60s | 多长时间检查一次缓存中的条目是否超出非活动时长。建议值:小于等于open_file_cache inactive |
open_file_cache_min_use | http, server, location | open_file_cache_min_uses number; | 1 | 在open_file_cache inactive指定的时长内被访问超过此处指定的次数时,才不会被删除(删除低命中率的缓存)。 |
Gzip压缩相关配置
配置选项 | 上下文 | 语法 | 默认值 | 功能描述 |
gzip | http, server, location, if in location | gzip on | off; | off | 开启内容压缩,可以有效降低客户端的访问流量和网络带宽 |
gzip_min_length | http, server, location | gzip_min_length length; | 20s | 内容超过最少长度后才开启压缩,因为太短的内容压缩效果不佳,且压缩过程还会浪费系统资源。这个压缩长度会作为http响应头Content-Length字段返回给客户端。 建议值:64 |
gzip_comp_level | http, server, location | gzip_comp_level 1~9; | 1 | 压缩级别,默认值为1。范围为1~9级,压缩级别越高压缩率越高,但对系统性能要求越高。建议值:4 |
gzip_types | http, server, location | gzip_types mime-type …; | text/html | 压缩内容类型,默认为text/html;。只压缩html文本,一般我们都会压缩js、css、json之类的,可以把这些常见的文本数据都配上。如:text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript; |
配置变量
Nginx配置文件支持使用变量,可以使用内置变量或自定义变量。用户自定义变量语法:set var_name value;http核心模块的内置变量(http://nginx.org/en/docs/varindex.html),主要有如下:
$uri:当前请求的uri,不带参数
$request_uri:请求的uri,带完整参数
$host:http请求报文中host首部;如果请求中没有host首部,则以处理此请求的主机的主机名代替
$hostname:nginx服务运行所在主机的主机名
$remote_addr:客户端IP
$remote_port: 客户端port
$remote_user:使用用户认证时客户端用户输入的用户名
$request_filename:用户请求中的URI经过本地root或alias转换后映射的本地的文件路径
$request_method:请求方法
$server_addr:服务器地址
$server_name: 服务器名称
$server_port:服务器端口
$server_protocol:服务器向客户端发送响应时的协议,如http/1.1,http/1.0
$scheme:在请求中使用的scheme 映射协议本身的协议
$http_HEADER:匹配请求报文中指定的HEADER,$http_host匹配请求报文中的host首部
$sent_http_HEADER:匹配响应报文中指定的HERDER,例如$http_content_type匹配相应报文中的content-type首部
$document_root:当前请求映射到的root配置
if 判断语句
if是URL地址重写ngx_http_rewrite_module模块中的选项。
在location中使用if语句可以实现条件判断,其通常有一个return语句,且一般与有着last或break标记的rewrite规则一同使用。但其也可以按需要使用在多种场景下,需要注意的是,不当的使用可能会导致不可预料的后果。if语句中的判断条件匹配用法如下:
正则表达式匹配:
==: 等值比较;
~:与指定正则表达式模式匹配时返回"真",判断匹配与否时区分字符大小写;
~:与指定正则表达式模式匹配时返回"真",判断匹配与否时不区分字符大小写;
!~:与指定正则表达式模式不匹配时返回"真",判断匹配与否时区分字符大小写;
!~:与指定正则表达式模式不匹配时返回"真",判断匹配与否时不区分字符大小写;
文件及目录匹配判断:
-f, !-f:判断指定的路径是否为存在且为文件;
-d, !-d:判断指定的路径是否为存在且为目录;
-e, !-e:判断指定的路径是否存在,文件或目录均可;
-x, !-x:判断指定路径的文件是否存在且可执行;比如:
if ($request_method == “PUT”) { #判断请求方法
}=======================
if ($ request_uri ~ “.(jpg|gif|jpeg|png)$”){ #判断URL是否是以这些结尾的图片
}
nginx命令行参数
nginx 仅有数个命令行参数,完全通过配置文件来配置。通过"nginx –h"可以查看,如下:
常用选项:
-c </path/to/config> 为 Nginx 指定一个配置文件,来代替缺省的。
-t 不运行,而仅仅测试配置文件。nginx 将检查配置文件的语法的正确性,并尝试打开配置文件中所引用到的文件。
-v 显示 nginx 的版本。
-V 显示 nginx 的版本,编译器版本和配置参数。