一、Nginx介绍
1.1 功能描述
Nginx的功能包括基本的HTTP功能和扩展功能。和Apache服务器一样,Nginx服务器为了提供更多的功能并且能够有效地扩展这些功能,使用了模块化的方式来扩展其功能。每一个模块都提供了一个功能,通过编译这些功能模块来实现功能的扩展。
1.2 基本HTTP功能
■ 提供静态文件和index文件,生成自动索引,打开文件描述符缓存;
■ 使用缓存加速反向代理,简单的负载均衡和容错;
■ 使用缓存机制加速远程FastCGI服务器的访问,简单的负载均衡和容错;
■ 模块化的结构,过滤器包括gzip、字节range、chunk响应、 XSLT、SSI和图像大小调整(确切地说是将大图转换为小图)过滤,被传递到后台度武器(FastCGI或者是代理服务器)多个SSI指令在单个页面的并行处理;
■ 支持SSL 和 TLS SNI。
1.3 扩展HTTP功能
■ 基于名称和基于IP的虚拟服务器;
■ 支持Keep-alive 和管道连接;
■ 灵活的配置;
■ 重新配置和在线升级而不用终端对客服访问的处理;
■ 访问日志的格式,缓存日志写入和快速日志轮询;
■ 3xx-5xx 错误代理重定向;
■ 重写模块;
■ 基于客户端IP地址和HTTP基本认证的访问控制;
■ 基于HTTP协议的PUT,DELETE,MKCOL,COPY和MOVE方法;
■ FLV流文件;
■ 速度限制;
■ 限制同时连接数或者是来自同一个IP地址的请求;
■ 嵌入式Perl语言解析;
1.4 架构和扩展性:
■ 一个master进程和几个workers进程,workers进程有非特权用户运行;
■ 消息通知方法:epoll(Linux 2.6+),kqueue(FreeBSD 4.1+),rt singnals(Linux 2.2.19+),/dev/poll(Solaris 7 11/99+),event ports(Solaris 10).select,and poll;
■ 支持kqueue的各个功能,包括EV_CLEAR,EV_DISABLE(禁用临时事件),NOTE_LOWAT,EV_EOF,number of available data,错误代码;
■ 支持sendfile(FreeBSD 3.1+, Linux 2.2+, Mac OS X 10.5), sendfile64 (Linux 2.4.21+),和sendfilev(Solaris 8 7/01+);
■ AIO(FreeBSD 4.3+, Linux 2.6.22+) 支持;
■ 支持Accept-filters(FreeBSD 4.1+) 和TCP_DEFER_ACCEPT(Linux 2.4+);
■ 10000个非活动HTTP keep-alive连接仅用掉2.5MB内存;
■ 数据复制操作控制在最低限速。
总结:非拥塞、事件驱动、单线程、一个master和N个worker、高效的资源使用、高度的模块化;
二、Nginx模块介绍
Nginx核心模块:包括Nginx的内核模块(CoreModule)和事件驱动模块(EventsModule);
HTTP服务模块:这类模块包括三类模块,即HTTP的内核模块(HTTPCoreModule)和标准模块以及可选的HTTP模块。
2.1 Nginx的核心模块
①. 配置示例
# user nginx;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
②. 核心模块指令
指令名称:error_log
语法:error_log file [ debug | info | notice | warn | error |crit ]
默认值:$(prefix)/logs/error.log
功能:用于Nginx服务器(包括FastCGI) 指定记录错误日志文件和记录错误的级别。日志的级别有debug、info 、 notice 、 warn 、 error 、crit (详细程度由高到低:debug提供了全部日志记录,而crit仅报告了关键错误)。
注意:不要认为设置error_log off能够关闭日志记录功能,相反这样会将日志写入到一个文件名为off的文件中。如果想关闭错误日志功能,则可是使用一下配置:
error_log /dev/null crit;
指令名称:lock_file
语法:lock_file file
功能:Nginx使用了连接互斥锁进程顺序的accept()系统调用,如果使用Nginx使用gcc、Intel C++或者是SunPro C++在i386、amd64、sparc64和ppc64编译创建,那么Nginx服务器将自动采用异步互斥进程访问控制,而在其他情况下锁文件会被使用,默认是不使用,除非在编译时开启了该功能。
例如:
lock_file /var/log/lock_file;
指令名称:pid
语法:pid /var/log/nginx.pid;
功能:用于设定Nginx的pid文件位置。
指令名称:include
语法:inculde file|*
功能:用于载入配置文件。如果没有指定绝对路径,那么文件的路径将会和配置文件的目录关联,换而言之,Nginx会认为与配置文件在同一目录下;
例如:
include conf/ssl.conf
include vhosts/*.conf
指令名称:timer_resolution
语法:timer_resolution t
功能:指令用于缩短gettimeofday()系统调用的时间,默认情况下gettimeofday()在kevent()、epoll、/dev/poll、select()及poll()调用完成之后调用。如果在具体的使用中需要一个笔记标准的时间来记录$upstream_response_time或者$msec变量。那么将会使用到该指令。
例如:timer_resolution 100ms;
指令名称:user
语法:user user [group]
功能:如果master进程是以root用户来运行的,那么Nginx将会使用setuid()/setgid()来实现UER/GROUP的接替工作。如果没有指定GROUP,那么Nginx将会使用同USER一样的组名称。默认情况下,使用nobody用户名称和nobody组名称;或者在配置./configure 脚本时指定--user=USER 和--group=GROUP来实现。
指令名称:worker_cpu_affinity
语法:worker_cpu_affinity cpumask ...;
功能:该指令只能用于Linux,设置worker进程与CPU的亲和力。该指令允许通过调用sched_setaffinity() 将worker进程绑定到一个CPU上。
例如:
worker_processes 4;
worker_cpu_affinity 0001 0010 0100 1000;
# 设置将每一个进程绑定到一个CPU上。
worker_processes 2;
worker_cpu_affinity 0101 1010;
# 设置将第一个worker绑定到CPU0/CPU2;将第二个worker绑定到CPU1/CPU3;
对于超线程(HTT) CPU合适。
指令名称:worker_priority
语法:worker_priority [-] number
功能:指令用于指定worker进程的优先级,从-20(最高级)到19(最低级),默认为0;
注意:Kernel进程运行在-5优先级,因此不建议设置-5或更小;
指令名称:worker_processes
语法:worker_processes Number
功能:如果Nginx提供SSL或者gzip,即对CPU的使用率较高,并且系统中有两个以上的CPU或者内核,那么可以设置worker_processes的值为CPU的数量或者是内核的数量。如果提供了大量的静态文件,并且中的数量超过了有效的内存大小,那么可以增加该指令的值,以便于充分利用磁盘的宽带。另外,如果想要将worker进程保定到某个CPU或者内核上,则可以使用worker_cpu_affinity指令。
建议:worker线程的个数;通常应该为物理CPU核心个数减1;
指令名称:worker_rlimit_nofile
语法:worker_rlimit_nofile limit
功能:用于定义一个worker进程可以同时处理的文件数量,也就是说一个worker进程所能够打开的最大文件句柄数;
名称名称:worker_rlimit_sigpending
语法:worker_rlimit_sigpending Number
功能:定义每一个用户(调用进程的用户ID)能够被排入队列的信号(signals)数量。如果队列(queue)满了,但由于这个限制,信号(signals)会被忽略,也就是说每个用户能够发往worker的信号的数量;
2.2 Nginx事件模块
①.配置示例
events {
worker_connections 1024;
}
②.时间模块指令
指令名称:accept_mutex_delay
语法:accept_mutex_delay Nms;
默认值:500ms
功能:如果一个工作进程 (worker process) 没有互斥锁,那么它将至少在这个设定值的时间之后才会被回收。
指令名称:worker_connections
语法:work_connections number
默认值:1024
功能:该指令用于设置每个worker进程所处理的连接数。
通过worker_connections和 worker_processes指令能够计算最大客户端连接数:
max_clients = worker_processes * worker_connections
在反响代理的环境中,最大客户端连接数变为:
max_clients = worker_processes * worker_connections/4
原因在于,默认情况下一个浏览器会对服务器打开两个连接,Nginx使用来自于同一个池中的FDS(文件描述符)来连接上游的服务器。
指令名称:use
语法:use type
功能:如果在执行./configure 的时候指定了不只一个事件模型,那么在使用Nginx时候可以通过该指令告诉Nginx想使用的事件驱动模型。默认情况下,Nginx在编译时会检测系统,并且Nginx会根据所在操作系统选择一个最适合的事件驱动类型。可选择的值:/dev/poll、epoll、eventport、kqueue、rtsig、或select。
指令名称:multi_accept
语法:multi_accept [ on| off ]
功能:定义Nginx是否立即接收从所有监听队列进入的连接。也就是说 multi_accept会在Nginx接到一个新的连接后立即发出通知后调用accept()来接收尽量多的连接。
指令名称:accept_mutex
语法:accept_mutex [ on | off ]
默认值为:on
功能:Nginx使用连接互斥锁(mutex) 进行顺序的accept()系统调用。
指令名称:accept_mutex_delay
语法:accept_mutex_delay Nms;
功能:定义一个worker进程在尝试再次获取资源之前应等待的时间。如果指令accept_mutex设置为off,那么该值(指的是accept_mutex_delay的值),如果不能使用。单位为毫秒(milliseconds)。
2.3 Nginx的HTTP核心模块
①、配置结构
http {
...
server {
listen 80;
server_name www.sharelinux.com;
....
location / {
root html;
index index.html index.htm;
...
}
}
}
②.HTTP核心模块指令
指令名称:aio
语法:aio [ on | off | sendfile ]
使用环境:http, server , location
功能:对应Linux来说还需要配合使用directio指令。另外如果使用了该指令,那么将会自动禁用sendfile的支持。
例如:
location /video {
aio on;
directio 512;
output_buffers 1 128k;
}
指令名称:alias
语法:aliasfile-path|directory-path
功能:该指令用于指定一个路径、但是不同于root指令;
例如:
location /i/ {
alias /webroot/p_w_picpaths/;
# 这里可以理解为:把/webroot/p_w_picpaths/看做为/i/,p_w_picpath目录下的文件和i目录下的文件一一对应;
}
location /m/ {
root /webroot/p_w_picpaths/;
# 这里可以理解为:把/webroot/p_w_picpaths/映射为i目录所在的根/。p_w_picpath目录下还需要建立m目录;
}
注意:root表示指明路径为对应location的“ /” URL;alias表示路径映射,即location中的URL是相对于alias所指明的路径而言;如果还是不理解可以查看访问日志;
指令名称:client_body_in_single_buffer
语法:client_body_in_single_buffer
功能:用于指定是否将整个客户端的请求保存在单个请求缓存中。为了减少复制操作,当使用变量$requset_body的时候推荐使用该指令。
注意:当请求体不能被单个缓存(参照client_body_buffer_size)容纳下的时候,那么请求体将会保存在磁盘上。
指令名称:client_body_buffer_size
语法:client_body_buffer_size the_size
默认值:8k/16k
功能:指定客户端请求体缓存的大小。如果请求体大于该缓存大小,那么整个请求体或者请求体的某些部分将会被写入临时文件。
默认值等于两个页面大小,页面的大小依赖于所在的操作系统平台,可能是8k或者是16k。当请求中Conten-Length的值小于指定缓存的大小时,那么Nginx将会使用较小的一个缓存,因此Nginx也并非总是为每一个请求分配指定大小的缓存。
指令名称:client_body_temp_path
语法:client_body_temp_path dir-path [ level1 [level2 [level 3 ] ] ]
默认值:client_body_temp
功能:用于指定一个存储临时文件的目录,在这个目录中将会存储客户端请求body体。按照指定子目录等级,可能也会有三级目录。例如:
client_body_temp_path /tmp/nginx/clent_temp 1 2;
那么目录的存储结构将会是:
/tmp/nginx/clent_temp/6/36/00001234568
指令名称:client_body_timeout
语法:client_body_timeout N;
默认值:60
功能:该指令用于设置读取客户端请求标题的超时时长。这个超时仅指一个请求的请求头还没有进入请求头的读取步骤时的超时时长,如果在这个设定的时长内客户端没有发送任何数据,那么Nginx将返回“Request time out ” (408)。
指令名称:client_max_body_size
语法:client_max_body_size 1m
功能:用于设定客户端请求体的最大值,在客户端请求中通过Content-Length表明。如果客户端请求体大于指定的值,那么客户端将会收到一个“
Request Entity Too Large”(413) 的错误。
指令名称:default_type
语法:default_type MIME-type
默认值:default_type text/plain
功能:用于指定一个默认的MIME类型,对于没有标准的MIME匹配的文件类型将会使用该类型。
指令名称:directio
语法:directio [ size | off ]
功能:用于启动O_DIRECT (FreeBSD,Linux),F_NOCACHE (Mac OS X)标志或者directio()函数(Solaris),对于大于该指定大小的文件,那么僵启用这种方式读取该文件。如果启动该指令,则将禁用sendfile。例如:
directio 4m;
指令名称:error_page
语法:error_page coed [code...] [=| =answer-code ] URI | @name_location
功能:用于指定一个URI,在访问出错的时候将会显示该页面。
error_page 404 /404.html;
error_page 502 503 504 /50x.html;
error_page 403 http://www.sharelinux.com/forbiddent.html;
error_page 404 - @fetch;
还可以通过该指令将一个状态码改变为另一个状态码。例如:
error_page 404 =200 /empty.gif;
error_page 404 =403 /forbidden.gif;
另外,还可以通过等号 ‘=’来使用自己设计的错误处理程序来决定指定错误代码的返回状态,例如:
error_page 404 = /404.php
注意:这个“=”后没有状态码
如果重定向中不需要改变URI,那么可以通过以下方法将错误处理传递到一个命名的location中:
location / {
error_page 404 @fallback;
}
location @fallback {
proxy_pass http://backend;
}
指令名称:keepalive_disable
语法:keepalive_disable [ msie6 | safari | none ]
默认值:msie6 safari
功能:用于禁用某些用户带来的keepalive功能。
指令名称:keepalive_timeout
语法:keepalive_timeout [ time ] [ time ]
默认值:keepalive_timeout 75
功能:该指令有两个参数,第一个参数用于设定客户端keep-alive连接超时,在这个时间过后,服务器将会关闭连接。第二个选项是一个可选项,它的值决定了响应头Keep-Alive:timeout="time"的值,这个头能够告诉一些浏览器关闭连接,这样故武器就不用再次关闭连接了。如果没有设置这个参数,那么Nginx将不会发送Keep-Alive头,两个参数的值可以不相同。
指令名称:keepalive_requests
语法:keepalive_requests N
默认值:keepalive_requests 100
功能:用于设置Nginx服务器能够保持活跃的连接数。
指令名称:large_client_header_buffers
语法:large_client_header_buffers Number Size
默认值:large_client_header_buffers 4 4k/8k
功能:指令用于指定客户端一些比较大的请求头使用的缓冲区数量和大小。
指令名称:limit_except
语法:limit_except methods {...}
功能:该指令用于限制访问location 的HTTP方法。例如:
limit_except GET {
allow 192.168.1.0/24;
deny all;
}
指令名称:limit_rate
语法:limit_rate speed
功能:用于限制流量
指令名称:limit_rate_after
语法:limit_rate_after time
默认值:limit_rate_after 1m
功能:用于限制流量
指令名称:listen
语法:listen address:port [ default_server | [ backlog=num | rcvbuf=size | sndbuf=size | accept_fiter=filter | deferred |bind|ipv6only=[on|off] | ssl ]]
功能:用于指定Server{...}区段设置接收请求的IP地址和端口。可以仅指定一个IP地址、一个端口或者是一个服务器的名字作为地址,例如:
listen 127.0.0.1;
listen 127.0.0.1:8080;
listen *:8088;
listen localhost:8000
这些参数必须跟随在default_server参数之后。
backlog=num参数:指定调用listen(2)时backlog的值,默认为-1;
rcvbuf-size参数用于设置监听套接字的SO_RCVBUF参数值;
sndbuf-size参数用于设置监听套接字的SO_SNDBUF参数值;
accept_filter=filter参数:设置过滤器的名字,该参数仅用于FreeBSD,有两个过滤器dataready和httcodeady;
deferred参数:设置该参数表示延时accep(2)t 在Linux中使用TCP_DEFER_ACCEPT选项;
bind参数:该参数指定将bind(2)分开调用;
ssl参数:该参数用于监听SSL。
例如:
listen 80;
listen 443 default_server ssl;
指令名称:location
语法:location[=|~|~*|^~|[@] /uri/ ] {...}
功能:允许根据用户请求的URI来匹配定义的各location,匹配到时,此请求将被相应的location块中的配置所处理;
=: 精确匹配检查;
~: 正则表达式模式匹配,区分字符大小写;
~*:正则表达式模式 匹配,不区分字符大小写;
^~:URI的前半部分匹配,不检查正则表达式;
匹配优先级:精确匹配(=)、^~、~和~*、由不带符号的URL进行左侧匹配;
指令名称:open_file_cache
语法:open_file_cache max = N [inactive = time ] | off
默认值:open_file_cache off
指令选项:
Max:该选项用于指定缓存条目的最大值,当缓存满后,根据最近最少(LRU)算法将缓存条目移除;
Inactive:用于指定一个非活动时间,如果在这个时间内缓存的条目没有被访问,那么该条目将会被删除,默认值为60秒;
Off:禁止缓存;
可以缓存的信息如下:
打开文件的描述符、文件的大小和修改时间信息;
目录存在性的信息;
在搜索文件过程中出现的错误信息---找不到文件、没有读取的权限等。
open_file_cache max=1000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
指令名称:open_file_cache_errors
语法:open_file_cache_errors on|off
默认值:open_file_cache_errors off
功能:开启或禁用缓存文件错误。
指令名称:open_file_cache_min_uses
语法:open_file_cache_min_uses number
默认值:open_file_cache_min_uses 1
功能:用于指定的时间内一个文件被访问的最少次数,如果访问的次数大于这个值,那么该文件的描述符将会被缓存到缓存中。
指令名称:open_file_cache_valid
语法:open_file_cache_valid time
默认值:open_file_cache_valid 60
功能:指定了检测缓存信息的间隔(与open_file_cache指令相关)。
指令名称:root
语法:root path
默认值:root html
功能:指定了一个请求的根文档目录。
指令名称:satisfy
语法:satisfy [ all | any ]
All:需要所有条件都有效;
Any:至少一个有效;
例如:
localtion / {
satisfy any;
allow 172.16.0.1/24;
deny all;
auth_basic "Closed site";
auth_basic_user_file conf/.htpasswd;
}
客户端访问该资源有两个条件。
使用satisfy all,客户端必须满足以上两个条件才能够访问该资源;使用satisfy any,客户端只需要满足任意一个条件就可以访问该资源;
指令名称:send_timeout
语法:send_timeout Time
默认值:send_timeout 60
功能:设置响应超时,当超过这个设定的时间后,Nginx将会关闭一个不活动的连接。当一个连接变为非活动状态的那一刻起,客户端便停止传输数据。需要注意的是,这个超时的确定不是整个传输响应的时间,而是两个读操作之间的时间,如果在这个时间内,客户端没有进行任何操作,那么Nginx将会关闭连接。
指令名称:sendfile
语法:sendfile [ on|off ]
默认值:sendfile off
功能:用于设置是否使用sendfile(),由于这种方法是在内核中进行操作的,因此sendfile()比read(2)和write(2)的写作操作更有效,这是由于read-wirte有一个从用户空间传递数据的过程。
指令名称:server
语法:sever {...}
功能:用于设置虚拟主机。
指令名称:server_name
语法:server_name name […]
功能:指令执行以下两个动作。
将进入的HTTP请求的主机头(Host header) 与Nginx配置文件中各个Server{...}区段比较,并且选择第一个被匹配的Server区段---这就是如何确定虚拟主机。服务器名字(Server name) 按照以下顺序处理:
① 全域名,静态域名;
② 开始部分使用通配符的域名,例如:*.sharelinux.com;
③ 结尾部分使用通配符的域名,例如:www.sharelinux.*;
④ 带有正则表达式的域名;
如果没有找到匹配的server,那么会按照下面的顺序在配置文件中选择一个server{...};
① 匹配listen指令被标记为:[ default|default_server ]的server区段;
②匹配listen指令(或着隐含有listen 80)的第一个server区段(或者隐含有listen 80)
指令名称:tcp_nodelay
语法:tcp_nodelay [on|off]
默认值:tcp_nodelay on
功能:用于允许或禁止使用套接字选项TCP_NODELAY。这个选项只对keep-alive连接有效。
指令名称:tcp_nopush
语法:tcp_nopush [on|off]
默认值:tcp_nopush off
功能:用于允许或禁止使用套接字选项TCP_NOPUSH(在FreeBSD系统中)或者TCP_CORK(在Linux系统中),该选项仅在使用sendfile时有效。如果tcp_nopush设置为on,那么Nginx将会尝试在被一个TCP数据包中发送整个HTTP响应头。
指令名称:try_files
语法:try_files path1 [path2] uri
功能:用于顺序检测文件的存在性,并返回第一个找到的文件。$uri/表示是一个目录,即$uri之后紧跟一个斜线"/"。如果没找到文件,那么最后的参数内部重定向将会被使用,最后一个可以使用的参数必须存在,否则将会产生内部错误。不像rewrite,$args不会自动保存,因此如果最后的蚕丝不是一个命名的location,则需要明确指出。
例如:
try_files $uri $uri/ /index.php?q=$uri$args;
指令名称:types
语法:types {…}
功能:用于设置响应请求文件的文件类型。默认的映射如下:
types {
text/html html;
p_w_picpath/git git;
p_w_picpath/jpeg jpg;
}
完整的映射表包含在conf/mime.types中。
Nginx工作原理:
三、Nginx模型设计与Linux五种IO模型
3.1 同步和异步:synchronous, asynchronous
关注的是消息通知机制;
同步:调用发出不会立即返回,但一旦返回就可以返回最终结果;
异步:调用发出之后,被调用方立即返回消息,但返回的非最终结果;被调用者通过状态、通知机制来通知调者,或通过回调函数来处理结果;
3.2 阻塞和非阻塞:block, nonblock
关注的是调用等等调用结果(消息、返回值)时的状态
阻塞:调用结果返回之前,调用者(调用线程)会被挂起;调用者只有在得到结果之后才会返回;
非阻塞:调用结果返回之前,调用不会阻塞当前线程;
3.3 五种I/O模型;
阻塞型IO [blocking IO]
非阻塞型IO [nonblocking IO]
复用型IO [IO multiplexing] (slect,poll复用器) 备注:httpd pefork,httpd worker
信号驱动型IO [signal driven IO] (epoll) 备注:httpd event
异步IO [asyncrhonous IO] 备注:nginx
3.4 其IO工作流程模型:
②. 非阻塞IO模型
③. 复用IO模型
④.信号驱动IO模型
⑤. 异步IO模型
四、Nginx设计架构图: