Ngingx的特点
(1)模块化设计,较好的扩展性
(2)高可靠性
master(控制)-->worker
(3)较低的内存消耗
10000个keep-alive连接在Nginx仅消耗2.5M
(4)支持热部署
不停机而更新配置文件、更换日志文件、更新服务器程序版本
基本功能:
静态资源的web服务器,能缓存打开的文件描述符
http,smtp,pop3协议的反向代理服务器,缓存,负载均衡
支持fastCGI(fpm)
模块化,非DOS机制,重新编译Nginx,过滤器zip,SSI及图像大小调整
支持SSL
扩展功能:
基于名称和IP的虚拟主机
支持keepalive
支持平滑升级
定制访问日志,支持使用日志缓冲区提高日志存储性能
支持url rewrite
支持路径别名
支持基于IP及用户的访问控制
支持速率限制,支持资源限制
Nginx的基本架构
一个master进程看,生成一个或多个worker
事件驱动:Linux->epoll(是linux上处理大并发网络连接的利器)solaris->event ports,FreeBSD->kqueue
消息通知:select,poll,rt signals
支持sendfile,sendfile64(系统调用可以高效的把硬盘中的数据发送到网络上)
支持AIO
支持mmap
nginx:非阻塞、时间驱动、一个master生成一个或多个worker、每个worker响应n个请求
模块类型:wiki.nginx.org/Modules
核心模块
标准HTTP模块
可选HTTP模块
mail模块
第3方模块
Nginx配置文件主要结构
main配置段
http {
}
mail {
}
配置指令要以分号结尾,语法格式:
directive value1 [value2];
支持使用变量:
模块内置变量
自定义变量
set var_name value
ngx_http_core_mode模块提供的变量
$arg_PARAMETER ==>HTTP请求中某个参数的值,如/index.html?size=100,可以用$arg_size 取得100 这个值
$args ==>HTTP请求中的完整参数。例如,在请求/index.html?_w=120&_h=120中,$args表示字符串_w=120&_h=120
$binary remote_ addr ==>二进制格式的客户端地址.例如:\x0A \xE0B\x0E
$body_bytes_sent ==>表示在向客户端发送的http响应中,包体部分的字节数
$content_length ==>表示客户端请求头部中的Content-Length字段
$content_type ==>表示客户端请求头部中的Content-type 字段
$cookie_COOKIE ==>表示在客户端请求头部中的cookie字段
$document_root ==>表示当前请求所使用的root 配置项的值
$uri ==>表示当前请求的URI,不带任何参数
$document_uri ==>与$uri 含义相同
$request_uri ==>表示客户端发来的原始请求URI ,带完整的参数。$uri和$document_uri 未必是用户的原始请求,在内部重定向后可能是重定向后的URI ,而$request_uri永远不会改变,始终是客户端的原始URI
$host ==>表示客户端请求头部中的Host 字段。如果Host 字段不存在,则以实际处理server(虚拟主机)名称代替。如果Host 字段中带有端口,如IP:PORT,那么$host 是去掉端口的,它的值为IP。$host 是全小写的。这些特性与http_HEADER 中的http_host 不同,http_host只是“忠实”地取出Host头部对应的值
$hostame ==>表示Nginx所在机器的名称,与gethostbyname 调用返回的值相同
$http_HEADER ==>表示当前HTTP 请求中相应头部的值。HEADER名称全小写。例如,用$http_host 表示请求中Host 头部对应的值
$sent_http_HEADER ==>表示返回客户端的HTTP 响应中相应头部的值。HEADER 名称全小写。例如,用$sent_http_content_type表示响应中Content-Type 头部对应的值
$is_args ==>表示请求中的URI 是否带参数,如果带参数, $is_args 值为?,如果不带参数,则是空字符串
$limit rate ==>表示当前连接的限速是多少, 0 表示无限速
$nginx _version ==>表示当前Nginx 的版本号,直11 1.0.14
$query_string ==>请求URI 中的参数,与$args 相同,然而$query_string 是只读的不会改变
$remote addr ==>表示客户端的地址
$remote port ==>表示客户端连接使用的端口
$remote user ==>表示使用Auth Basic Module 时定义的用户名
$request_filename ==>表示用户请求中的URI 经过root 或alias 转换后的文件路径
$request_ body ==>表示HTTP 请求中的包体,该参数只在proxy_pass 或fastcgi_pass 中有意义
$request_body_file ==>表示HTTP 请求中的包体存储的临时文件名
$request_ completion ==>当请求已经全部完成时,其值为"ok"。若没有完成,就要返回客户端,则其值为空字符串:或者在断点续传等情况下使用HTTP range 访问的并不是文件的最后一块,那么其值也是空字符串
$request_ method ==>表示HTTP 请求的方法名,如GET 、PUT 、POST 等
$scheme ==>表示HTTP scheme,如在请求https://nginx.com/中表示https
$server addr ==>表示服务器地址
$server name ==>表示服务器名称
$server_port ==>表示服务器端口
$server _protocol ==>表示服务器向客户端发送响应的协议,如HTTP/1.1 或HTTP/1.0
main段配置
用于调试、定位问题
1、daemon[off|on]; ==>脱离终端并且在后台运行的进程。它脱离终端是为了避免进程执行过程中的信息在任何中断上显示,这样一来,进程也不会被任何终端所产生的信息所打断。Nignx是一个需要以守护进程方式运行的服务,因此,默认都是以这种方式运行的。方便跟踪调试Nginx。
2、master_process on|off; ==>是否以master/worker模式运行nginx,yes只启动master
3、error_log/path/to/error_log level; ==>错误日志文件及其级别;出于调试的目的,可以使用debug级别,但此级别只有在编译nginx时使用了--with-debug选项才有效
正常运行必备的配置
1、user USERNAME [GROUPNAME]; ==>指定运行worker进程的用户和组,在configure命令执行时使用--user=username和--group=groupname;例如: user nginx nginx;
2、pid /path/to/pid_file; ==>指定nginx的pid文件。默认与configure执行时的参数"--pid-path"所指定的路径是相同的
3、worker_rlimit_nofile #; ==>指定一个work进程所能够打开的最大文件句柄数
4、worker_rlimit_sigpending #; ==>指定每个用户能够发往worker的信号的数量,当某个用户的信号队列满了,这个用户再发送的信号量会被丢掉
优化性能的配置
1、worker_processes #; ==>通常应该为物理CPU核心个数减1
2、worker_cpu_affinity cpumask ...; ==>绑定worker进程指定的CPU上0001,0010,0100,1000分别表示第1,2,3,4颗CPU;例如worker_cpu_affinity 00000001 00000010 00000100; 仅对Linux系统有效。Linux操作系统使用sched_setaffinity()系统调用实现这个功能
3、timer_resolution #; ==>每次内核的事件调用(如epoll、select、poll、kqueue等)返回时,都会执行一次gettimeofday,实现用内核时钟来更新Nginx中的缓存时钟。gettimeofday的执行代价不小,因为中间有一次内核态到用户态的内存复制。但目前大多数内核中,x86-64体系架构,gettimeofday只是一次vsyscall,仅仅对共享内存中的数据访问,并不是通常的系统调用,代价并不大,一般不必使用这个配置。如果希望日志文件每行打印的时间更准确,可以使用它。
4、worker_priority nice; ==>进程所分配的CPU时间片大小与进程优先级先关,优先级越高,进程分配到的时间片也就越大,最小的时间片只有5ms,最大的时间片有800ms。优先级由静态优先级和内核根据进程执行情况所做的动态调整共同决定。如果用户希望Nginx占有更多的资源,那么可以把nice值配置得更小一些,但不建议比内核进程的nice值(通常为-5)还要小。
5、ssl_engine device; ==>如果服务器上有SSL 硬件加速设备,那么就可以进行配置以加快SSL 协议的处理速度。用户可以使用OpenSSL 提供的命令来查看是否有SSL 硬件加速设备:openssl engine -t
事件相关的配置
1、accept_mutex[on|off] ==>是否打开accept;是Nginx的负载均衡锁,让多个worker进程轮流地、序列化与新的客户端建立TCP连接。当某一个worker进程建立的连接数量达到worker_connections配置的最大连接数的7/8时,会打打地减小该worker进程视图建立新TCP连接的机会,以此实现所有worker进程之上处理的客户端请求数量尽量接近。accept默认是打开的,如果关闭它,那么建立TCP连接的耗时会很短,但worker进程之间的负载会非常不均衡,因此不建议关闭它。
2、lock_file /path/to/lock_file; ==>lock 文件的路径;accept锁可能需要这个lock文件,如果accept锁关闭,lock_file配置完全不生效。如果打开了accept锁,并且由于编译程序、操作系统架构等因素导致Nginx不支持原子锁,这时才会用到文件锁实现accept锁,这样lock_file指定的lock_file指定的lock文件才会生效。
3、accept_mutex_delay #ms; ==>使用accept 锁后到真正建立连接之间的延迟时间;在使用accept锁后,同一时间只有一个worker进程能够取到accept锁。这个accept锁不是阻塞锁,如果取不到会立即返回。如果有一个worker进程试图去accept锁而没有取到,它至少要等accept_mutex_delay定义的时间间隔后才能再次视图取锁。
4、use [ kqueue | rtsig | epoll | /dev/poll | select | poll | eventport ]; ==>选择事件模型;Nginx会自动是使用最合适的时间模型。Linux操作系统来说,可供选择的时间驱动模型有poll,select,epoll三种。epoll是性能最高的一种。
5、worker_connections #; ==>每个worker 的最大连接数
http配置段
http core 配置一个静态web服务器
ngx_http_core_module
配置框架:
http {
upstream{
server
...
}
server{
listen IP:PORT
#虚拟主机
location /URL{
if..{
../.
}
root "/path/to/somenwhere"
....
}
}
server{
#虚拟主机
}
}
注意:与http配置相关的指令必须放在http、server、location、upstream、if块中
网络连接相关的配置:用于http,server,location
1、keepalive_timeout time; ==>保持连接的超时时长,默认为75s
2、keepalive_requests #; ==>在一次连接上允许承载最大资源请求数,默认100个
3、keepalive_disable [msie6|safari|none] ==>为指定类型的游览器经用长连接
4、tcp_nodelay on|off ==>对长连接是否使用TCP_NODELAY选项 小包延迟发送,影响性能
5、client_header_timeout time; ==>读取http请求报文首部的超时时长
6、clinet_body_timeout time ==>读取http请求报文body的超时时长 上传
7、send_timeout time ==>发送响应报文的超时时长
8、client_header_timeout 60; ==>读取HTTP 头部的超时时间;超时,并向客户端返回408 (”Request timed ut”}响应。
9、client_body_timeout 60; ==>读取HTTP 包体的超时时间
10、send_timeout 60; ==>发送晌应的超时时间;Nginx 服务器向客户端发送了数据包,但客户端一直没有去接收这个数据包。如果某个连接超过send_timeout 定义的超时时间,那么Nginx 将会关闭这个连接。
11、reset_timedout_connection off; ==>连接超时后将通过向客户端发送RST 包来直接重置连接;注意,使用RST 重置包关闭连接会带来一些问题,默认情况下不会开启。
12、lingering_close off I on I always; ==>该配置控制Nginx 关闭用户连接的方式。always 表示关闭用户连接前必须无条件地处理连接上所布用户发送的数据。。眼示关闭连接时完全不管连接上是否已经有准备就绪的来自用户的数据。on 是中间值,一般情况下在关闭连接前都会处理连接上的用户发送的数据,除了有些情况下在业务上认定这之后的数据是不必要的。默认on
13、lingering_time 30s; ==>lingering_ close 启用后,这个配置项对于上传大文件很有用。上文讲过,当用户请求的Content-Length 大于max_client_body_size 配置时, Nginx 服务会立刻向用户发送413(Requestentity too large )晌应。但是,很多客户端可能不管413 返回值,仍然持续不断地上传HTTPbody,这时,经过了lingering_time 设置的时间后, Nginx 将不管用户是否仍在上传,都会把连接关闭掉。
14、lingering_timeout 5s; ==>lingering_ close 生效后,在关闭连接前,会检测是否有用户发送的数据到达服务器,如果超过lingering_timeout 时间后还没有数据可读,就直接关闭连接:否则,必须在读取完连接缓冲区上的数据井丢弃掉后才会关闭连接。
对客户端请求进行限制:
1、limit_execpt METHOD {...} ==>按HTTP 方法名限制用户请求;指定对范围之外的其他方法的访问控制
除GET之外的,允许172.16.0.0/16
2、client_body_max_size 1m; ==>HTTP 请求包体的最大值;限制请求报文中body部分的上限,通过请求报文首部中的"Content_Length"来判定,如用户上传一个10GB的文件,收到后发现Content——Length超过地址的值,就发送413"Request Entity Too Large"响应给客户端
3、limit_rate speed ==>对请求的限速;限制客户每秒钟传输的字节数,默认为0,表示无限制
4、limit_rate_after 1m; ==>表示Nginx向客户端发送的响应长度超过limit_rate_after后才开始限速
对内存或磁盘资源进行分配
1、client_body_in_file_only on | clean | off ; ==>HTTP 包体只存储到磁盘文件中;请求报文的body部分是否可暂存于磁盘;on表示允许,并且即使请求结束,也不会删除暂存的内容;clean表示会删除;off不允许暂存;默认为off
2、client_body_in_single_buffer on | off ==>HTTP 包体尽量写入到一个内存buffer 中;用户请求中的HTTP 包体一律存储到内存buffer 中。当然,如果HTTP 包体的大小超过了client_body_ buffer_ size 设置的值,包体还是会写入到磁盘文件中。,默认为off
3、client_header_buffer_size size ==>存储HTTP 头部(包含HTTP行和HTTP头部)的内存buffer 大小;有时,请求中的HTTP header 部分可能会超过这个大小,这时large_client_ header_ buffers 定义的buffer 将会生效。默认1K
4、large_client_header_buffers number size ==>存储超大HTTP 头部的内存buffer 大小;一个超大HTTP头部请求的buffer个数和每个buffer的大小,如果HTTP请求行(如GET/index HTTP/1.1)的大超过上面的单个buffer,则返回"Request URI too large"(414)。请求中一般会有许多header,每一个header的大小也不能超过单个buffer的大小,否则会"Bad request"(400)。当然,请求行和请求头部的总和也不可以超过buffer个数*buffer大小,默认 large_client_header_buffers 4 8k;
5、client_body_buffer_size size; ==>存储HTTP 包体的内存buffer 大小;HTTP包体会先接收到指定的这块缓存中,之后才决定时候写入磁盘,如果用户请求中含有HTTP头部Content-Length,并且其标识的长度小于定义的buffer大小,那么Nginx会自动降低本次请求所使用的内存buffer,以降低内存消耗。默认8K/16K
6、client_body_tmp_path DIR[level1 [ level2 [ level3]]]; ==>HTTP包体存放的临时目录;在接收HTTP包体时,如果包体的大小大于client_body_buffer_size,则会以一个递增的整数命名并存放到client_body_temp_path指定的目录中。level是为了防止一个目录下的文件数量太多,从而导致性能下降,因此使用了level参数,这样可以按照临时文件名最多再加三层目录
· 字符父和2个字符子目录
7、connection _pool_ size 256
8、request_pool_size 4K
MIME类型相关的配置: 配置块:http、server、location
1、types{} ==>定义MIME types至文件的扩展名
2、default_type MIME-TYPE; ==>默认text/plain;当找不到相应的MIME type与文件扩展名之间的映射时,使用默认的MIME type作为HTTP header中的Content-Type
3、types_hash_max_size 1024; ==>为了快速寻找到相应MIME type,Nginx使用散列表来存储MIME type和文件扩展名。值越大,消耗内存越多,散列key的冲突率降低,速度快。
文件操作优化相关的配置 配置块:http 、server 、location
1、sendfile on | off ==>sendfile系统调用。默认off,启用后用sendfile发送文件减少了内核态与用户态之间的2次内存复制,这样就会从磁盘中读取文件后直接在内核态发送到网卡设备,提高了发送文件的效率
2、aio on | off ==>AIT系统调用。在FreeBSD或Linux系统上启用内核级别的异步文件I/O功能。与sendfile功能互斥。默认为off
3、directio size | off ==>linux系统上使用O_DIRECT选项去读取文件,缓冲区大小为size,通常对大文件的读取速度有优化作用,性能差一般不开启,和sendfile互斥
4、directio_alignment size; ==>与directios配合使用。指定directio方式读取文件时的对齐方式。一般512B,linux下的XFS需要设置到4KB作为对齐方式。
5、open_file_cache max=N [ inactive=time ] | off; ==>打开文件缓存,通过读取缓存减少对磁盘的操作。
nginx可以缓存一下三种信息:
(1)文件句柄、文件大小和上次修改时间
(2)已经打开过的目录结构
(3)没有找到的或者没有权限操作的文件信息
max=N:在内存中存储的最大条目;一旦达到上限,则会使用LRU从缓存中删除最近最少使用的条目
inactive=time:在inactive指定的时长内没有被访问过的缓存条目就会淘汰,默认60s
6、open_file_cache_errors on | off; ==>是否在文件缓存中缓存打开文件时出现的找不到路径、没有权限等错误信息。
7、open_file_cache_min_uses time; ==>open_file_ cache 中的inactive 参数配合使用。如果在inactive 指定的时间段内,访问次数超过了open_file_ cache_ min_ uses 指定的最小次数,那么将不会被掏汰出缓存。
8、open_file_cache_valid 60s ==>检验缓存中元素有效性的频率