官方文档 http://nginx.org/en/docs/http/ngx_http_core_module.html、
中文文档 http://www.nginx.cn/doc/standard/httpcore.html
翻译比较详细中文文档 http://shouce.jb51.net/nginx/left.html
建议两个文档个都看看防止遗漏中文文档不全
Nginx的HTTP配置主要包括三个区块,结构如下:
http://shouce.jb51.net/nginx/StandardHTTPModules/HTTPCore.html
location
语法:location [=|~|~*|^~|@] /uri/ { ... }
默认值:no
使用字段:server
这个参数根据URI的不同需求来进行配置,可以使用字符串与正则表达式匹配,如果要使用正则表达式,你必须指定下列前缀:
1、~* 不区分大小写。
2、~ 区分大小写。
要确定该指令匹配特定的查询,程序将首先对字符串进行匹配,字符串匹配将作为查询的开始,最确切的匹配将被使用。然后,正则表达式的匹配查询开始,匹配查询的第一个正则表达式找到后会停止搜索,如果没有找到正则表达式,将使用字符串的搜索结果。
在一些操作系统,如Mac OS X和Cygwin,字符串将通过不区分大小写的方式完成匹配(0.7.7),但是,比较仅限於单字节的语言环境。
正则表达式可以包含捕获(0.7.40),并用于其它指令中。
可以使用“^~”标记禁止在字符串匹配后检查正则表达式,如果最确切的匹配location有这个标记,那么正则表达式不会被检查。
使用“=”标记可以在URI和location之间定义精确的匹配,在精确匹配完成后并不进行额外的搜索,例如有请求“/”发生,则可以使用“location = /”来加速这个处理。
即使没有“=”和“^~”标记,精确的匹配location在找到后同样会停止查询。
下面是各种查询方式的总结:
1、前缀“=”表示精确匹配查询,如果找到,立即停止查询。
2、指令仍然使用标准字符串,如果匹配使用“^~”前缀,停止查询。
3、正则表达式按照他们在配置文件中定义的顺序。
4、如果第三条产生一个匹配,这个匹配将被使用,否则将使用第二条的匹配。
例:
location = / { # 只匹配 / 的查询. [ configuration A ] }
location / { # 匹配任何以 / 开始的查询,但是正则表达式与一些较长的字符串将被首先匹配。 [ configuration B ] }
location ^~ /images/ { # 匹配任何以 /images/ 开始的查询并且停止搜索,不检查正则表达式。 [ configuration C ] }
location ~* \.(gif|jpg|jpeg)$ { # 匹配任何以gif, jpg, or jpeg结尾的文件,但是所有 /images/ 目录的请求将在Configuration C中处理。 [ configuration D ] }
各请求的处理如下例:
·/ -> configuration A
·/documents/document.html -> configuration B
·/images/1.gif -> configuration C
·/documents/1.jpg -> configuration D
注意你可以以任何顺序定义这4个配置并且匹配结果是相同的,但当使用嵌套的location结构时可能会将配置文件变的复杂并且产生一些比较意外的结果。
标记“@”指定一个命名的location,这种location并不会在正常请求中执行,它们仅使用在内部重定向请求中。(查看error_page和try_files)
例如:
1:没有修饰符 表示:必须以指定模式开始,如:
server {
server_name xxxx.com;
location /abc {
……
}
}
那么,如下是对的:
http://xxxx.com/abc
http://xxxx.com/abc?p=1
http://xxxx.com/abc/
http://xxxx.com/abcde
2:= 表示:必须与指定的模式精确匹配,如:
server {
server_name xxxx.com;
location = /abc {
……
}
}
那么,如下是对的:
http://xxxx.com/abc
http://xxxx.com/abc?p=1
如下是错的:
http://xxxx.com/abc/
http://xxxx.com/abcde
3:~ 表示:指定的正则表达式要区分大小写,如:
server {
server_name xxxx.com;
location ~ ^/abc$ {
……
}
}
那么,如下是对的:
http://xxxx.com/abc
http://xxxx.com/abc?p=1
如下是错的:
http://xxxx.com/ABC
http://xxxx.com/abc/
http://xxxx.com/abcde
4:~* 表示:指定的正则表达式不区分大小写,如:
server {
server_name xxxx.com;
location ~* ^/abc$ {
……
}
}
那么,如下是对的:
http://xxxx.com/abc
http://xxxx.com/ABC
http://xxxx.com/abc?p=1
如下是错的:
http://xxxx.com/abc/
http://xxxx.com/abcde
5:^~ 类似于无修饰符的行为,也是以指定模式开始,不同的是,如果模式匹配, 那么就停止搜索其他模式了。
6:@ :定义命名location区段,这些区段客户段不能访问,只可以由内部产生的请 求来访问,如try_files或error_page等
查找顺序和优先级
1:带有“=“的精确匹配优先
2:没有修饰符的精确匹配
3:正则表达式按照他们在配置文件中定义的顺序
4:带有“^~”修饰符的,开头匹配
5:带有“~” 或“~*” 修饰符的,如果正则表达式与URI匹配
6:没有修饰符的,如果指定字符串与URI开头匹配
HTTP代理模块
httpProxy中文文档 http://shouce.jb51.net/nginx/StandardHTTPModules/HTTPProxy.html
http://www.nginx.cn/doc/standard/httpproxy.html
httpProxy官方文档 http://nginx.org/en/docs/http/ngx_http_proxy_module.html
Nginx通常被用作后端服务器的反向代理,这样就可以很方便的实现动静分离, 以及负载均衡,从而大大提高服务器的处理能力。 http Proxy模块,功能很多,最常用的是proxy_pass
Nginx实现动静分离(location),其实就是在反向代理的时候,如果是静态资源,那么就直 接从Nginx发布的路径去读取,而不需要从后台服务器获取了。
但是要注意:这种情况下需要保证后端跟前端的程序保持一致,可以使用Rsync 做服务端自动同步或者使用NFS、MFS分布式共享存储。
HTTP负载均衡模块
中文文档http://shouce.jb51.net/nginx/StandardHTTPModules/HTTPUpstream.html
http://www.nginx.cn/doc/standard/httpupstream.html
官方文档 http://nginx.org/en/docs/http/ngx_http_upstream_module.html
server
语法:server name [parameters]
默认值:none
使用字段:upstream
指定后端服务器的名称和一些参数,可以使用域名,IP,端口,或者unix socket。如果指定为域名,则首先将其解析为IP。
·weight = NUMBER - 设置服务器权重,默认为1。
·max_fails = NUMBER - 在一定时间内(这个时间在fail_timeout参数中设置)检查这个服务器是否可用时产生的最多失败请求数,默认为1,将其设置为0可以关闭检查,这些错误在proxy_next_upstream或fastcgi_next_upstream(404错误不会使max_fails增加)中定义。
·fail_timeout = TIME - 在这个时间内产生了max_fails所设置大小的失败尝试连接请求后这个服务器可能不可用,同样它指定了服务器不可用的时间(在下一次尝试连接请求发起之前),默认为10秒,fail_timeout与前端响应时间没有直接关系,不过可以使用proxy_connect_timeout和proxy_read_timeout来控制。
·down - 标记服务器处于离线状态,通常和ip_hash一起使用。
·backup - (0.6.7或更高)如果所有的非备份服务器都宕机或繁忙,则使用本服务器(无法和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;
}
注意:如果你只使用一台上游服务器,nginx将设置一个内置变量为1,即max_fails和fail_timeout参数不会被处理。
结果:如果nginx不能连接到上游,请求将丢失。
解决:使用多台上游服务器。
upstream
语法:upstream name { ... }
默认值:none
使用字段:http
这个字段设置一群服务器,可以将这个字段放在proxy_pass和fastcgi_pass指令中作为一个单独的实体,它们可以可以是监听不同端口的服务器,并且也可以是同时监听TCP和Unix socket的服务器。
服务器可以指定不同的权重,默认为1。
示例配置
upstream backend {
server backend1.example.com weight=5;
server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
server unix:/tmp/backend3;
}
请求将按照轮询的方式分发到后端服务器,但同时也会考虑权重。
在上面的例子中如果每次发生7个请求,5个请求将被发送到backend1.example.com,其他两台将分别得到一个请求,如果有一台服务器不可用,那么请求将被转发到下一台服务器,直到所有的服务器检查都通过。如果所有的服务器都无法通过检查,那么将返回给客户端最后一台工作的服务器产生的结果。
负载均衡算法
ll+weight 默认的负载算法:
ip_hash : 基于Hash 计算
应用场景:保持session 一至性
url_hash: (第三方)
应用场景:静态资源缓存,节约存储,加快速度
least_conn 最少链接
least_time 最小的响应时间,计算节点平均响应时间,然后取响应最快的那个,分配更高权重。
ip_hash
语法:ip_hash
默认值:none
使用字段:upstream
这个指令将基于客户端连接的IP地址来分发请求。
哈希的关键字是客户端的C类网络地址,这个功能将保证这个客户端请求总是被转发到一台服务器上,但是如果这台服务器不可用,那么请求将转发到另外的服务器上,这将保证某个客户端有很大概率总是连接到一台服务器。
无法将权重(weight)与ip_hash联合使用来分发连接。如果有某台服务器不可用,你必须标记其为“down”,如下例:
upstream backend {
ip_hash;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com down;
server backend4.example.com;
}
请注意:这个方法本质还是轮询,而且由于客户端的ip可能是不断变化的,比如动 态ip,代理,翻墙等等,因此ip_hash并不能完全保证同一个客户端总是由同一 个服务器来处理。
Geo和GeoIP模块
geo
语法:geo [$ip_variable] $variable { ... }
默认值:none
使用字段:http
这个指令指定了一个客户端IP的所属国家,默认情况下它会查找$remote_addr变量,但在0.7.27版本以后可以手工指定。
geo $arg_remote_addr $geo {
...;
}
使用CIDR地址格式,另外,有4个特殊的参数:
·delete - 删除指定的网络(0.7.23)
·default - 将一些没有定义的地址替换为0.0.0.0/0。
·include - 具有地址信息的文本文件,可以包含多个。
·proxy - 指定代理服务器地址(0.8.7)。
·ranges - 指定使用以地址池的形式定义地址(0.7.23),这个参数必须放在首位。
geo $country {
default no;
include conf/geo.conf;
127.0.0.0/24 us;
127.0.0.1/32 ru;
10.1.0.0/16 ru;
192.168.1.0/24 uk;
}
conf/geo.conf文件内容:
10.2.0.0/16 ru;
192.168.2.0/24 ru;
该值将使用最大的参数,例如127.0.0.1将为“ru”,而不是“us”。
一个使用ranges的例子:
geo $country {
ranges;
default no;
127.0.0.0-127.0.0.0 us;
127.0.0.1-127.0.0.1 ru;
127.0.0.1-127.0.0.255 us;
10.1.0.0-10.1.255.255 ru;
192.168.1.0-192.168.1.255 uk;
}
http{
geo $geo{
default default;
202.103.10.1/24 A;
179.9.0.3/24 B;
}
upstream default.server{
server 192.168.0.100;
}
upstream A.server{
server 192.168.0.101;
}
upstream B.server{
server 192.168.0.102;
}
server{
listen 80;
location / {
proxy_pass http://$geo.server$request_uri;
}
}