第一部分:HTTP基础知识
在介绍nginx常用模块中的指令时,先来回顾一下http的相关知识:
1、http的工作原理
http的工作原理大致是这样的:
a)、客户端与服务器先建立一个TCP连接;
b)、客户端通过已建立的TCP连接向服务端发送一个http请求报文;
c)、服务器收到请求报文后开始解析报文、定位所请求的资源,读取资源并封装成响应报文后发送给客户端;
d)、如果没有启用持久连接,服务器端主动断开tcp连接,客户端被动关闭;如果启用了持久连接,那该tcp连接保持一段时间后,在该时间内客户端可利用此tcp连接断续请求资源;
f)、客户端接收到响应报文后解析此报文(html文档),并在浏览器上给予显示。
2、http的两个重要特性
a)、http的无状态性:同一个客户端两次连续的访问服务器端,服务器不会知道这两个请求是来自同一个客户端,服务器不会意识到这个客户端在前不久已访问过,服务器端也无法识别不同的客户端。http的这种无状态性让http的设计更为简单高效,更能让服务器能承载高并发的http请求。
b)、http的持久连接:在http1.0时不支持持久连接,意味着每一个请求客户端与服务端都需要建立一个新的tcp连接,而tcp是一种可靠的连接,每一次连接都需要经过三次握手,每一次断开都需要经过四次断开,而当今互联网环境下,一个页面上的资源多达数十个,那打开一个页面速度会很慢,这种短连接的方式也加重了网络的负担。http1.1开始支持keepalive持久连接,允许客户端与服务端的TCP连接建立后保持一段时间,在接下来的请求中可以利用此TCP连接进行资源的请求与响应。而http1.1的持久连接也有两种模式:一种叫非流水线的持久连接,这种持久连接表示客户端在没有接收到上一次请求的响应报文时不能再发送第二次的请求报文;另一种叫做流水线的持久连接,这种持久连接表示客户端在没有接收到上一次请求的响应报文时依然可能发送第二次请求报文。
3、http协议请求报文与响应报文格式
请求报文格式如下图(图片来自网络):
请求报文包括请求行、请求头部和请求包体三部分,如上图所示。
响应报文格式如下图(图片来自网络):
响应报文包括状态行、响应头部和响应包体三部分,如上图所示。
4、http的响应码
1XX:纯属状态信息码,表示请求收到,断续处理
2XX:成功响应码,行为被成功接受、理解与采纳
3XX:重定向类,为了完成请求,必须进一步执行动作
4XX:客户端错误,请求包含语法错误或者请求的资源不存在
5XX:服务器错误,服务器不能实现一种明显无效的请求
第二部分:nginx的常用配置
nginx是一个高度模块化的架构,它分为以下几类模块:
nginx是一个高度模块化的架构,它分为以下几类模块:“nginx core module”(nginx核心模块)、“standard http modules”(标准模块)、“optional http modules”(可选模块)、“mail modules”(邮件相关的模块)、“third party modules”(第三方模块)。此博文只对nginx核心模块和HTTP核心模块中常用的指令用法作介绍,在nginx核心模块中的指令中,根据指令的功能不同,也可把这些指令归成几个类别,下边就慢慢道来。
nginx核心模块的指令用于配置在nginx.conf的main段,作用于nginx自身启动的特性设置,作用域是main、envents、http、server、mail各段,nginx核心模块中保证nginx正常启动必备的几个指令:
1、user USER [GROUP];
指定运行worker进程的用户和组,组可省略,那就表示使用user所在的组作为worker进程的组。
2、pid FILE;
指定nginx的pid文件。
3、worker_rlimit_sigpending LIMIT;
设定每个用户能够发往worker进程的信号数量,即指定信号队列的大小,这个指令现在已被nginx官方删除,不再支持此指令。
与优化相关的指令(main配置段)
1、worker_processes NUMBER | AUTO;
指定nginx启动时启动worker进程的个数,以cpu的核心为基准,其值一般为cpu的物理核心数减去1或2,留下1到2个核心让系统本身使用,默认值是1。
2、worker_cpu_affinity CPUMASK;
让worker进程绑定在指定的cpu核心上,这个指令只能用于Linx和FreeBSD的系统上。比如:
worker_processes 4;
worker_cpu_affinity 0001 0010 0100 1000;
表示启动4个worker进程并分别绑定在了cpu0、cpu1、cpu2、cpu3上。
如果cpu已开启了超线程技术,那建议如下的配置:
worker_processes 2;
worker_cpu_affinity 0101 1010;
表示启动两个worker进程,把第一个进程绑定在cpu0和cpu2上,把第二个进程绑定在cpu1和cpu3上。
3、ssl_engine DEVICE;
在拥有ssl硬件加速的服务器上指定硬件ssl设备,让硬件设备来维持ssl会话
4、timer_resolution INTERVAL;
每次内核的事件调用(假如epool)返回时,都会使用gettimeofday()来更新nginx的缓存时钟,此值用于定义多长时间才由gettimeofday()更新一次缓存时钟,单位为“ms”,在x86的服务器上,gettimeofday()的代价极低,可忽略些指令的设定
5、worker_priority NUMBER;
NUMBER的范围(-20,19),指定worker进程的优先级别,值越小优先级越高,默认是0
6、worker_rlimit_nofile SIZE;
指定一个worker进程能够打开的最大文件句柄数,设置此值可以在突破系统的限制而不重新启动主进程。默认时一般是1024个,在高并发环境下需要加大此值,一般设置为51200。
与事件相关的配置(events{})
1、accep_mutex on | off;
默认已开启, 是否打开nginx的负载均衡锁,因nginx是以master-worker进程模型工作,worker的接收请求是由master进程来分配,设置此选项为“on”,master进程会逐个分配新的请求给各worker进程,否则(设置为off)每个worker进程都会收到有新请求的通知,在少量请求的环境下,一些worker进程可能只是在浪费资源而已。当worker进程的负载达到其上限的7/8时,master就尽可能不再将请求分配给此worker。
2、lock_file FILE;
nginx利用锁定机制来实现accep_mutex和序列化对共享内存的访问,此值设定锁文件的存放路径,默认在“lock_file logs/nginx.lock;”。
3、accept_mutex_delay TIME;
假如accept_mutex设置为on,这里的TIME表示如果一个worker进程正在处理一个新连接,而另一个进程又想取得accept锁来处理新请求这期间,worker进程需要等待的最大时长,默认是500ms。
4、multi_accept on | off;
假如设置为off,worker进程一次将接受一个新的连接请求,否则worker进程将一次所有的新连接请求,默认是off。
5、use [epoll|rtsig|select|poll];
定义nginx连接处理事件的方法,方法有“select、poll、kqueue、epoll”,nginx将默认使用最有效的方法来处理事件,所以此指令不用显式的定义。
6、worker_connections NUM;
定义一个worker进程能够并发响应的最大连接数。
用于调试、定位问题的配置(main段)
1、daemon on | off;
是否让nginx运行于后台,默认是"on",在调试时应该设置为“off”,使所有信息输出到标准输出,主要是开发者使用。
2、master_process on | off;
是否以master-worker模型运行,默认是“on”,调试时可设置为“off”,主要是开发者使用。
3、error_log /path/to/error_log LEVEL;
设置错误日志文件及其级别,调试时把level设置为debug,默认是error级别,但在编译安装时需要“--with-debug”开启此功能。
与http(web)服务相关的配置
nginx必须使用虚拟主机来提供站点,每个虚拟主机需要一个"server{}"段来配置,非虚拟主机或公共配置,需要放在server{}之外,http{}之内。
1、server{}
定义一个虚拟主机,支持基于主机名、基于IP、基于端口的虚拟主机
2、listen IPADDRESS[:PORT];
listen中的各子指令:
default_server:定义此server为http中默认的server,如果所有的server{}中没有一个使用此参数,那第一个server{}就是默认
rcvbuf=SIZE:设置接收监听在套接字的接收缓冲大小
sndbuf=SIZE:设置接收监听在套接字的发送缓冲大小
ssl:表示这是一个https server
3、server_name SERVER_NAME;
可以跟多个主机名,名称中可以使用通配符(以"~"开头),当nginx收到一个请求时,会取出"Host"首部,然后跟所有的server_name进行比较。比较方式为:
a、先做精确匹配:
b、左侧通配符匹配:
c、右侧通配符匹配:
d、正则表达式匹配:
4、server_name_hash_bucket_size 32|64|128
为了实现快速主机查找,nginx使用hash表来保存主机名,此指令用来设置存放hash table的大小。
5、location,有两种模式,第一种:“location [ = | ~ | ~* | ^~ ] uri { ... } ”,第二种:“ location @name { ... }”
功能:根据用户请求的URI来匹配各个location,匹配到时将被location的控制策略所处理。
location后的操作符的意义:
=:精确匹配
~:正则表达式模式匹配,匹配时区分字符大小写
~*:正则表达式模式匹配,匹配时忽略字符大小写
^~:对URI的前半部分匹配,不检查正则表达式
匹配优先级:
先字符精确匹配,再正则表达式(多个正则表达都能匹配,那由第一个匹配到的处理),再按字符匹配
在location中与文件路径相关的指令:
a)、root PATH
设置web资源的存放路径,
举例:
location ^~/image/ {
root /photo;
}
如果访问的URL为“http://www.test.com/image/a.jpg",那此资源的存放路径为“/photo/image/a.jpg”,“image”是在"root /photo"定义的路径后的一个真实路径。
b)、alias PATH
设置路径别名
location ^~/image/ {
alias /photo;
}
如果访问的URL为“http://www.test.com/image/a.jpg",那此资源的存放路径为"/photo/a.jpg","image"就是一个虚拟的路径,在存储资源的路径中根本就没有,是一个虚假的访问路径,被匹配到时,被alias替换成了它定义的真实路径。
c)、index FILE ...;
定义默认主页,可跟多个值
d)、error page code ... [=[response]] uri;
当对某个请求返回错误时,如果匹配上了error_page指令中设定的code,则重定向到新的URI中,用来定义错误页面重定向,利用"=response"(response为响应码)可以定义返回给用户端的响应码成为自己定义的值。
f)、 try_files file ... uri;
依次去请求try_files后跟的文件,如果能请求到则返回给用户,如果后边接的file全部都尝试过了还是没有所请求的资源,则用定义的uri作为响应给用户。常用于错误文件的重定向。
例如:
location /documents/ {
root /www/htdocs;
try_files $uri /temp.html
}
这样定义表示当用户请求的uri中匹配到“/documents/”时,那就尝试去取得用户所请求的资源,如果用户所请求的资源不存在,刚用"/www/htdocs/temp.html"这个资源响应给用户。"$uri"表示把用户请求的每一个资源都赋予给这个变量进行查找相应资源的URI。
try_files file ... =code;
如果后边跟上一个“=code”,“code”是一个响应代码,那么在响应报文中会带上这个指定的响应码,例如:
location / {
try_files $uri $uri/index.html $uri.html =404;
}
这个例子表示用户访问网站根时,假设网站为
http://www.test.com,当用户访问http://www.test.com时,依次尝试访问http://www.test.com,http://www.test.com/index.html,http://www.test.com.html,如果都无法得到资源,那就把响应码设置成404。
与网络连接相关的设置
1、keepalive_timeout TIME;
定义保持连接的超时时间,默认是75秒,
2、keepalive_requests NUM;
定义在一个长连接上能够承载的最大请求数,即使没有达到keepalive_timeout定义的时间,只要达到最大请求数,那连接也将断开,默认是100。
3、keepalive_disable [msie6 | safari | none];
对指定的浏览器禁用长连接
4、tcp_nodelay on | off;
对keepalive连接是否使用tcp_nodelay选项,默认为“on”,在tcp中把数据送达到对方时,对方会给予一个确认数据收到的确认报文,delay就是表示延迟响应这个确认报文,把多个确认报文一起发给对方,tcp的性能能得到提升。但延迟响应在keepalive中会导致浏览器可能会错误认为对方没有收到已正确发送给对方的数据,因为在一定时间内没有收到确认报文,所以在keepalive的场景因关闭延迟确认,即“tcp_nodelay on”。
5、client_header_timeout TIME;
读取http请求首部的超时时间,单位为秒,默认是60秒
6、client_body_timeout TIME;
读取http请求的包体的超时时长,默认是60秒钟
7、send_timeout TIME;
发送http响应报文的超时时长,默认是60秒
对客户端请求的限制参数
1、limit_except method ... { ... }
限定指定范围之外方法的访问控制,例如:
limit_except GET {
allow 192.168.1.0/24;
deny all;
}
表示除了“GET”(或“HEAD”)方法之外的方法只有192.168.1.0网段才能使用
2、client_max_body_size SIZE;
限定http请求包体的最大值,默认是1M,常用于限定客户端所能够请求的最大包体,根据请求首部中的content_length来检测,以免无用的传输。
3、limit_rate SPEED;
限制客户端每秒传输的字节数,默认为0,表示没有限制
4、limit_rate_after SIZE;
nginx服务器端向客户端发送响应报文时,如果报文大小超出此处指定的大小后,则后续的发送过程开始使用limit_rate来限速。例如:
location /flv/ {
flv;
limit_rate_after 500k;
limit_rate 50k;
}
表示当用户访问的URI中匹配到“/flv/”后,且响应报文大于500k后,则后续的响应速度限制为50k/s
对文件操作的优化配置
1、sendfile on | off;
是否启用sendfile功能,建议启用
2、aio on | off;
是否启用aio功能,建议启用
3、open_file_cache off;
open_file_cache max=N [inactive=time];
是否打开文件缓存功能,max定义缓存元素的最大数量,当缓存填充满后根据LRU算法进行置换;inactive表示一个缓存条目在设置的时长没有被访问则自动被清理,默认时长为60秒。这里缓存的信息包括:文件句柄、文件大小、上次修改的时间,已经打开的目录结构,没有找到或没有访问权限的信息(这是由"open_file_cache_errors on | off"来控制是否缓存)。
4、open_file_cache_errors on | off;
在缓存时是否缓存因文件找不到或没有权限访问的相关信息。
5、open_file_cache_valid TIME;
多长时间检查一次缓存中的条目是否超出非活动时长,默认60秒,这个值应该与大于等于open_file_cache中的inactive=TIME中的值。
6、open_file_cache_min_uses NUM;
在open_file_cache中的inactive指定的时长内,被访问的次数超过这个指定的NUM值地,缓存条目才不会被删除,不然缓存条目在inactive指定的时长内被访问,但没有达到NUM值,依然会被清除。
对客户端请求的特殊处理
1、ignore_invalid_headers on | off;
是否忽略不合法的http首部请求,默认为on,off意味着请求中存在不合法的首部时不予响应。
2、log_not_found on | off;
用户请求的资源不存在时是否将这些资源找不到的相关信息也记录到错误日志中,
3、resolver_address;
指定nginx使用的dns服务器地址,用于解析upstream server的ip地址
4、resolver_timeout TIME;
指定dns解析的超时时间,默认为30秒
5、server_tokens on | off;
是否开启在响应报文“Server”字段中的信息和在服务器出错时的提示信息中是否包含nginx版本信息。
http核心模块的内置变量:
$uri
客户端请求的uri,不带参数部分
$request_uri
客户端请求的uri,带完整的参数部分
$host
http请求报文中的host首部,如果请求中没有host首部,则由处理此请求的虚拟主机的主机名代替。
$hostname
nginx服务运行在的主机的主机名
$remote_addr
客户端的IP
$remote_port
客户端的端口
$remote_user
使用用户认证时,客户端输入的用户名
$request_filename
指用户请求中的uri经过本地root或alias转换后映射的本地路径,即存放在本地磁盘的真实路径
$request_method
用户的请求方法
$server_addr
服务器地址IP
$server_name
nginx中配置的server_name的名称
$server_port
服务器端口,默认就是80
$server_protocol
服务器向客户端发送响应时的协议版本,如http/1.1
$scheme
在请求中使用的scheme,如https://www.test.com中的htts,即使用的协议
$http_HEADER
匹配请求报文中指定的HEADER,如: $http_host匹配请求报文中的host首部
$sent_http_HEADER
匹配响应报文中指定的HEADER,例如:$sent_http_content_type匹配响应报文中的content_type首部
$document_root
当前请求映射到的root指令配置的路径