1.下载地址
官网地址:NGINX - 免费试用、软件下载、产品定价 (nginx-cn.net)
我这边选择NGINX 开源版 nginx: download
2.nginx的基本配置
配置文件语法
配置文件组成:注释行,指令块配置项和一系列指令配置项组成。
单个指令组成:配置项名称和值参数,值参数可以是一个或多个附加参数,取决于解析该条指令的模块。
# user nobody;
worker_processes 4;
events {
worker_connections 1024;
}
块配置项组成:一个块配置顶名和一对大括号组成。 块配置后面是否带有参数,如location /webstatic {},取决于解析该配置块的模块。
- 指令配置项总是以分号结尾(;)。
- 字符“#”表示改行是注释行,nginx在读取配置文件时将忽略的文本。
指令特点
- 指令都有作用域,如上面例子,worker_connections 只能放在events区块才有意义。
- 配置块能相互嵌套。在某些情况下不同配置块能够相互嵌套。如在http区段,可以声明一个或多个server区段,server区段又可以插入一个或多个location区段。
- 最后同样重要的是配置的继承。在一个区段中嵌套其他区段,那么被嵌套的区段会继承其父区段的配置。在嵌套模块中重新声明指令会覆盖该继承。
指令值的单位
可以使用下面单位来指定配置文件所在上下文中指令值的单位。
- k或K:千字节
- m或M:兆字节
- ms:Milliseconds(毫秒)
- s:Seconds(秒)
- m:Minutes(分钟)
- h:Hours(小时)
- d:Days(天)
- w:Weeks(星期)
- M:Months(月)
- y:Years(年)
字符串值
注意:如果指令值中包含空格、分号或者是大括号等特殊字符,需要使用单引号或双引号将其括起。
nginx基本模块
nginx是由一系列模块组成的,大致可以分为核心模块、Http核心模块和其他模块。其中核心模块在编译时不能被禁用。核心模块包含main模块、events模块和include包含指令。
main模块重要指令
main模块位于配置文件根部。提供如进程管理和安全的能力。
daemon on; #启用或禁用守护进程模式。
user nobody; #worker进程运行的用户和组,如果没有提供则使用nginx的master进程的用户和用户组。
worker_processes 4;#定义worker进程数量一般和cpu核数一致。
#错误日志,这里的级别由debug,info,notice,warn,error和crit(debug记录了全部日志,crit仅报告关键错误)
#作用域:main, http, mail, stream, server, location
error_log logs/error.log error;
pid logs/nginx.pid; #存放nginx守护进程的pid文件路径。
log_not_found on; #开启或禁用记录404错误。
...
#除上面指令外还有worker_rlimit_core、worker_rlimit_nofile、worker_cpu_affinity、worker_priority等。
events模块
事件模块提供的指令可以用来配置网络机制
accept_mutex:on; #默认值on,启用或禁用使用一个接受互斥锁来打开套接字监听。
use epoll; #指定nginx所使用的网络事件模型,可选值有/dev/poll,epoll,kqueue等,通常不需要显式指定它,默认情况下nginx将使用最有效方法。
worker_connections 1024; #定义一个worker进程能够同时连接的数量。
configuration模块
提供的include 指令能够将其他文件包含在nginx配置文件中。在配置文件的任何地方均可插入该指令。注意如果没有指定绝对路径,那么文件路径将和配置文件的目录相关。
include /file/path.conf;
include sites/*.conf;
3.HTTP配置
HTTP 核心模块是Nginx中最大的一个模块,它包含了所有的基本的区段、指令和变量。
区段结构
通过下面的例子,来认识http模块的区段结构。
http {
#在http区段中启用gzip压缩
gzip on;
server {
server_name localhost;
listen 80;
location /downloads/ {
#在此location区段禁用gzip压缩
gzip off;
}
}
}
- http 区段位于配置文件的根部,在这个区段中允许定义HTTP模块的指令和HTTP模块的相关区段。
- server区段用于声明一个站点,该区段只能用在http区段中。
- location 区段应用于网站特定的URI位置,该区段能够用于server区段中,也能嵌套在其他location中。
模块指令
在http/server/location三个层次的每个层次都可以插入指令,下面介绍的指令都主要由http模块引入,对于每条指令都有它的使用环境。指令对应的级别包括http块、server块、location块,另外还有rewrite模块的if块。注意:一些指令不能用于某些级别。
下面介绍一些常见指令,如无特殊说明作用域为http,server,location。
套接字和主机配置指令
下表指令可以根据主机名或IP地址和端口的组合创建一个server区段。并通过一些指令来配置TCP套接字选项,以便调整网络设置。
- listen:用于设置监听套接字使用的ip端口号。
语法:listen [address][:port][其他选项]
其他选项:
default:指定监听的默认套接字,该server区段被用于默认的网站,在该IP地址和端口上接受任何客户端的请求。 ssl:指定的网站提供SSL服务。 其他选项依赖于bind和listen系统调用:backlog=num,rcvbuf=size,sndbuf=size,accept_filter=filter,deferred和bind。
作用域:server - server_name:在server区段中指定一个或多个主机名。
nginx收到http请求时,根据请求header中Host值与所有server区段比较,第一个与主机名匹配的server块将被选中,否则如果没有server区段与客户端请求的主机名匹配,nginx会选择第一个server区段,匹配监听参数(如listen *:80),另外具有default选项的listen会被优先选择。注意该指令接受通配符。
作用域:server
server_name www.website.com website.com;
server_name *.website.com;
server_name *.website.*;
- tcp_nodelay:开启或关闭使用TCP_NODELAY套接字选项,仅用于keep-alive连接。它禁用了Nagle 缓冲算法。
- tcp_nopush
开启或禁用TCP_NOPUSH(FreeBSD)或TCP_CORK(Linux)的scoket选项。如果tcp_nopush开启,则nginx将尝试在整个tcp数据包中发送整个http响应头。 - sendfile
指定nginx是否调用sendfile系统函数来输出文件,减少内核空间和用户空间的上下文切换。对于普通应用设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的负载。
另外还有sendfile_max_chunk、send_lowat等指令。
路径和文档
下表指令用来设置根目录、主页、错误页等。
- root:定义文档的根目录。
作用域:http,server,location,if。 - alias:location 指定uri路径的别名,它不会改变root的值。
作用域:location
location /i/ {
alias /spool/w3/images/;
}
#例如:请求"/i/top.gif",将返回这个文件: "/spool/w3/images/top.gif"。
#正如你所看到的,uri中location后面的部分会追加到这个目录后面,而location自身指定的uri路径是"丢弃的"
- error_page
允许修改访问URI所产生的HTTP相应代码,并选择性地将它替换为其他代码。
作用域:http,server,location,if。
语法:error_page code1 [code2 ...] [=replacement code] [=@block|URI]
例如:
error_page 404 html/404/html;
error_page 500 502 503 504 html/5x.html;
#跳转到命名的location区段。
error_page 404 @notfound;
#在出现404错误时 ,内部重定向到index.html,并且返回200 OK响应码。
error_page 404 =200/index/html;
- index:定义默认的页面,如果请求中没有指定文件名,nginx则使用默认页面提供服务。默认值index.html。
语法:index file1 [file2...]
#例如:
index index.php index.html index.htm;
- try_files:试图找到指定的文件,如果指定的这些文件都不是,就跳转到命名location区段(最后一个参数)或者指定的URI。
作用域:location。
#例如
location / {
try_files $uri $uri.php @proxy;
}
location @proxy {
proxy_pass 127.0.0.1:8080;
}
客户端请求
下面描述的是nginx处理客户端请求机制,如配置keepalive、客户端缓冲区设置等。
- keepalive相关指令:keepalive_requests、keepalive_timeout、send_timeout。
- 缓冲区相关指令:client_body_buffer_size、client_header_buffer_size、large_client_header_buffers等。
- 其他客户端指令:client_body_timeout、client_header_timeout、client_max_body_size、lingering_time、ligering_timeout、ignore_invalid_header等。
MIME类型
MIME类型会在HTTP响应头中Content-Type中发送,这个头通常影响浏览器对文件的处理,如MIME类型是application/octet-stream,那么浏览器会下载该文件,而非显示;如果MEMEE类型是text/plain,那么该文件在浏览器中会作为纯文本而不用html解释提供。
Nginx提供了两个配置MINE类型的指令。分别是types和default_types;
http {
include mime.types;
location /downloads/ {
#移除所有的MIME类型
types {};
default_type application/octet-stream.
}
}
记录相关
- log_not_found:开启或禁用404没有找到的HTTP错误,如果日志中由于找不到favicon.ico或robots.txt而充满404错误日志,则可以通过这个选项关闭掉。
作用域:http,server,location。
默认值:on - log_subrequest:启用或禁用记录子请求(被内部请求指令(如rewrite)或SSI请求触发的请求)。
作用域:http,server,location。
默认值:off
其他
除了以上介绍的指令外,还有限制和约束以及文件处理和缓存相关指令,需要时可查阅相关文档。 但这里有必要介绍下internal指令。
#internal:该指令指定location区段只能用于内部访问。内部重定向参考Rewrite模块。
server {
server_name *.website.com;
location /admin/ {
internal;
}
}
模块变量
HTTP核心模块引入了大量的变量,可以使用这些变量应用到配置文件中。nginx的变量分为请求头变量、响应头变量和Nginx产生的各种变量。
客户端请求头变量
nginx允许你可以访问客户端请求头,以$http_为前缀的格式访问,如下表。
- $http_host:HTTP头中的Host值。
- $http_referer:HTTP头中的referer值。
- $http_x_forward_for:HTTP头中的X-Forward-For的值。 除此之外还有$http_user_agent、$http_via、$http_cookie等。
响应头变量
这类变量发生在响应发送后,nginx允许你访问客户端响应头。以$send_http...为前缀,如下表。
- $send_http_content_type:HTTP头中的Content-Type的值。
- $send_http_content_length:HTTP头中的Content-Length的值。 除此之外还有$send_http_location、$send_http_connection等。
nginx产生的变量
- $arg_XXX:访问查询字符串中的参数。
- $args 所有结合在一起的查询字符串,同$query_string。
- $body_bytes_sent:在响应头中发送的字节数。
- $content_length:相当于HTTP头中的Content-Length。
- $content_type:相当于HTTP头中的Content-Type。
- $cookie_XXX:允许访问cookie数据,这里XXX替换为具体参数。
- $document_root:返回root指令的值。
- $document_uri:返回当前请求的uri,如果内部重定向被执行,将返回重定向后的uri。它与变量$uri相同。
- $request_uri:原始请求的uri,在整个处理过程中保持不变(不像$document_uri/$uri)。
- $host:相当于HTTP请求头中的Host,如果请求头没有Host,nginx会给这个变量赋一个值。
- $hostname:返回服务器的系统名称。
- $is_args:如果$args变量为空,那么$is_args也为空。
- $request_filename:返回当前请求文件的绝对路径。 除此之外还有$nginx_version、$hostname、$remote_addr、$request_body、$request_method、$server_name、$scheme等。
深入location区段
nginx location区段可以通过指定的模式与客户端请求URI相匹配,location区段语法如下:
Syntax: location [ = | ~ | ~* | ^~ ] uri { ... }
location @name { ... }
Default: —
Context: server, location
注意:location只是对URI进行匹配,不管查询字符串参数。
修饰符描述
- = :URI必须与指定模式精确匹配。这里的模式为简单字符串,不可使用正则表达式。
# uri必须与/abcd精确匹配(优先级最高),如:
# http://www.website.com/abcd 可用
location = /abcd {
...
}
- (无):URI必须以指定模式开始,不可使用正则表达式。
#uri必须与指定模式开始,以下uri可用:
# http://www.website.com/abcd
# http://www.website.com/abcd/
# http://www.website.com/abcde
location /abcd {
...
}
- ~:URI与指定的正则表达式模式匹配,区分大小写。
#正则表达式^/abcd$,指定模式必须以/开始,后根abc,以d字符结尾。如:
http://website.com/abcd 可用
http://website.com/abcd?param1¶m2 可用
location ~ ^/abcd$ {
...
}
- ~*:URI与指定正则表达式模式匹配,不区分大小写。
- ^~:URI以指定模式开始,如果模式匹配,则停止搜索其他模式,
- @ 定义命名location区段。这些区段只能由内部产生的请求访问,如try_files或error_page。
修饰符优先级
- =
- 无
- ^~
- ~或~*
- (无)
4.模块配置
主要有关Rewrite模块及可能会用到的其他模块。
Rewrite模块
nginx rewrite模块使用Perl兼容正则表达式库,在安装nginx时需要预先安装perl和perl-dev。
正则表达式
元字符
- ^ :以^后跟的字符开始
- $ :以$前的字符结尾
- . :匹配任何字符
- [ ] :组,匹配指定字符集合内的任何字符。
- [^ ] :否定组,匹配不包括在指定字符集内的字符。
- | :匹配符号“|”之前或之后的实体。
- ( ) :分组,组成一组匹配的实体,常和“|”配合使用。
- \ :对特殊字符进行转义。
量词
使用量词可以扩展实体匹配次数。
- *:0或多次
- +:1或多次
- ?:0或1次
- {x}:x次
- {x,}:至少x次
- {x,y}:x到y次
捕获
正则表达式最后一个功能是能够捕获自表达式,放在“( )”之间的任何文本,在被捕获后都能用于后面的处理。 例如:
server {
server_name website.com;
location ~* ^/(downloads|files)/(.*)$ {
add_header capture1 $1;
add_header capture2 $2;
}
}
关于内部请求
nginx有两种类型的内部请求:
- 内部重定向: nginx在内部重定向客户端的请求。URI被改变,请求可能匹配到其他的location区段。常见的内部重定向指令有error_page、rewrite、try_files。
- 子请求: 另一种触发内部请求而产生内容的就是子请求,如使用Addition模块或SSI模块的指令。
注意:error_log 日志级别设置为debug时能够捕获到内部请求日志,详情可参阅error_log指令。
rewrite模块指令
条件结构
Rewrite模块引入了if条件结构。
语法:if (condition) { ... }
作用域:server, location
条件运算符说明:
- 一个变量名 : 如果指定的变量或数据不等于空字符串或0,则条件为真。
- =或!= : 相等或不等比较
- ~ , ~* : 模式匹配,除此之外还有,!,!*
- -f,!-f : 测试文件是否存在
- -d,!-d : 测试一个目录是否存在
- -e,!-e : 测试文件、目录或符号链接是否存在
- -x,!-x : 测试文件是否存在且可执行。
例如:
if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /msie/$1 break;
}
if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
set $id $1;
}
if ($request_method = POST) {
return 405;
}
if ($slow) {
limit_rate 10k;
}
if ($invalid_referer) {
return 403;
}
注意:if和location都能实现类似的效果,它们的不同之处在于能够在这两个区段使用的指令不同。换句话说就是有些指令可以用在if区段,有的则不可以,但几乎所有指令都可以在location中使用。比较常见的是在if区段中使用rewrite指令。
rewrite
语法:rewrite regex replacement [flag];
如果指定的正则表达式与URI匹配,则URI将按照replacement指定的字符串进行更改。该rewrite指令将按其在配置文件中出现的顺序执行。可以使用flag终止指令的进一步处理。如果replacement以“http://”、“https://”或“$scheme”开头,则处理将停止并将重定向返回给客户端。 flag标志说明:
- last:停止处理后面的rewrite指令集,并使用新的URI重新发起一个内部请求。
- break:停止处理后面的rewrite指令集,相当于执行了break指令。如果重定向后的文件不存在返回404。
- redirect:临时重定向,返回302 Moved temporarily HTTP 重定向响应,Location Header显示跳转后的URL地址。
- permanent:永久重定向,返回301响应。
server {
...
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last;
rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra last;
return 403;
...
}
# 如上配置,如果放到location区块中,则last标志应该替换称break,否则nginx将执行10次循环,并返回500错误。
location /download/ {
rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;
rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra break;
return 403;
}
注意:
- 如果URI重写后发生循环,则重复该循环,但不超过10次。nginx将返回“500 Internal Server Error”。
- last和break都不再匹配后面的rewrite规则,但last应用完当前规则后,会重新发起一个内部请求查找一个location.
break
停止处理后面的rewrite指令集,阻止进一步改写请求URI。
if (-e $request_filename) {
break;
}
//因为break指令,后面的指令集不会执行
if ($uri ~ ^/search/(.*)$){
rewrite ^/search.php?q=$1;
}
return
中断请求处理过程,并返回一个指定的HTTP状态码。
语法:return code [text] | [codURL] ; return URL;
if ($uri ~ ^/admin/) {
return 403;
#因为已经完成了请求,此条指令不会执行。
rewrite ^ http://website.com;
}
set
初始化或重定义一个变量。注意有些变量不能修改,如$uri。
语法:set $variable value;
rewrite_log
如果设置为on,nginx将在“notice”错误级别对rewrite引擎处理的每个操作记录日志。
默认值:off
Log模块
该模块指令作用域:http,server,location
access_log:设置日志写入的路径,格式。
语法:access_log path [format [buffer=size] | off;
- path:日志记录的文件路径,路径中可以使用变量。
- format:用log_format指令声明一个模版名称。
- off:关闭日志记录
log_format:定义一个模版,用于表述日志中一个条目包含的内容。 语法:log_format template_name format_string; 默认的模版为combined。定义为:
log_format combined '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
变量
Log模块除了可以使用公用变量之外,也带来了下面一些新的变量,但这些变量只能在写日志条目时使用。
- $connection:连接号
- $msec:写入日志时的微秒时间
- $request_time:处理请求花费的总时间。
- $status:响应状态码
- $bytes_sent:发送到客户端的字节总数
- $body_bytes_sent:发送到客户端body的总字节数
- $reqeust_length 请求体长度。
此外还有$time_ios8601、$time_local、$connection_requests、$pipe几个变量。
headers模块
该模块允许将“ Expires”和“ Cache-Control”头字段以及任意添加响应头字段。主要有两个指令:
- add_header: 允许在响应头中添加一个新行。 如果响应码为200、204、301、302、304,则该行被添加到响应头中。可以在value中使用变量。如果指定了always参数,则无论响应码如何,都会添加到响应头。 语法:add_header name value [always];
- expires:该指令能够控制发送到客户端Expires和Cache-Control HTTP header的值,它影响的代码和前面一样。 语法:expires [modified] time | epoch | max | off;
参数说明:- time:过期时间值,如expires 30d;
- epoch:将文件有效期设置为January 1970。Cache-Control header设置为no-cache。
- max:将文件设置为Decemeber 31,2037。Cache-Control header被设置为缓存10年。
- off:两个头都不修改
referer模块
该模块有一个简单的指令:valid_referers。它的目的是检查来自客户端请求的referer HTTP头。如果referer被认为无效,则$invalid_referer设置为1。
语法:valid_referers none | blocked | server_names | string ...;
例如:
valid_referers none blocked server_names
*.example.com example.* www.example.org/galleries/
~\.google\.;
if ($invalid_referer) {
return 403;
}
注意:可以使用该模块实现网站防盗链功能,对其他网站链接的图片禁止访问。
Secure link模块
该模块与SSL模块无关,对访问的链接提供了基本的保护。该模块提供两种模式:
- 通过 secure_link_secret 指令启用,用于检查请求链接的真实性,和保护未授权的资源访问。
- 通过secure_link and和secure_link_md5 指令请用,也用于限制链接的生存周期。 常用作下载防盗链功能。
Image filter模块
该模块提供图像处理功能,通过GD Graphics Library(gdlib)来实现。默认编译的Nginx不包含这个模块
其他模块
除此之外比较重要的还有Index模块、gzip模块、realip模块、ssl模块等。另外在有特殊需要时还有 AutoIndex模块、auth_basic模块、Limit zone模块、Limit request模块,Empty GIF模块、Addtion模块、Gzip模块、Charset模块、Browser模块、GeoIp模块等等。其他模块根据需要查阅nginx文档。
5.fastcgi模块
基本概念:
- CGI协议(通用网关接口):描述了Web服务器和应用程序网关之间的信息如何交换。
- FastCGI:它是一个基于套接字的通信协议,使Web服务器能够将客户端请求转发到应用程序网关,它使用了能够处理多个请求的常驻进程,因而效率比较高。
默认情况下fastcgi模块默认是启用的,通过该模块提供的指令,能够使nginx将请求传递给FastCGI程序。
注意:nginx配置目录下的fastcgi.conf,包含了fastcgi预定义的一些参数。对所有fastcgi来说,有两个参数是必须的SCRIPT_FILENAME和QUERY_STRING。 例如:
#/etc/nginx/fastcgi.conf
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
....
#示例
location ~ \.php($|/) {
fastcgi_pass unix:/dev/shm/php.sock;
fastcgi_index index.php;
# 根据正则表达式分割为$fastcgi_script_name和$fastcgi_path_info两个变量。
# 比如请求/show.php/article/0001,被分割为/show.php和/article/0001
fastcgi_split_path_info ^(.+\.php)(/.*)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# 设置PATH_INFO SEVER变量
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param APP_ENV 'production';
include fastcgi.conf;
}
模块指令
下面简要介绍几个主要指令,其他指令用是可以查看官方文档。注意:如无特殊说明该模块指令作用域为:http、server、location
- fastcgi_pass:将请求转发给fastcgi服务器。 语法:fastcgi_pass address; 作用域:location, if in location
//对于TCP fastcgi_pass localhost:9000; //对于UNIX fastcgi_pass unix:/tmp/fastcgi.socket; - fastcgi_param:允许将配置传递给Fastcgi服务器。
- fastcgi_index:设置索引文件名,如果请求URI以斜杠结尾,则请求URI,带上由fastcgi_index指令附加上的索引文件名。
- fastcgi_split_path_info:根据正则表达式,将指令分割为$fastcgi_script_name和$fastcgi_path_info两个变量。
变量
- $fastcgi_script_name:请求uri.
6.upstream模块
upstream模块用来定义一组服务器,从而可以由proxy_pass,fastcgi_pass等指令引用。在upstream模块中,默认的方法是轮询,这种方法会带来Session会话问题,会出现同一个访问者的两个请求可能会被不同的两个服务器处理。
模块指令(整理自 nginx.org upstream模块 )
upstream:定义一组服务器,服务器可以监听不同端口,另外,可以混合监听TCP和UNIX域套接字。
语法:upstream name { ... }
作用域:http
注意:默认情况下,使用加权轮询均衡方法。在下面例子中,每7个请求,将有5个分配给172.16.0.50,第2和第3个服务器各一个请求。如果服务器通信期间发生错误,该请求将被传递到下一个服务器。依此类推,直到尝试所有正常运行的服务器为止,如果无法从任何一台服务器获得成功响应,则客户端收到最后一台服务器的响应结果。
示例:
upstream backend {
server 172.16.0.50 weight=5;
server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
server unix:/tmp/backend3;
server 172.16.0.49 backup;
}
除upstream指令外,其他指令的作用域是:upstream
server指令:定义后端服务器的地址和参数,这些参数将影响nginx对后端服务器的选择。
语法:server address [parameters];
参数说明:
- weight=n:设置服务器的权重,默认为1。注意:如果使用ip_hash模式,weight选项会被忽略。
- max_conns=number:限制连接到该服务器上的最大活动连接数,默认值为0,表示没有限制。作用是可以对单个服务器进行限流,防止服务器超负荷运转。
- max_fails=n:设置在fail_timeout参数设置的期间内与服务器通信失败的尝试次数,超过这个次数服务器将不可用,默认设置为1。认定失败的条件由proxy_next_upstream、fastcgi_next_upstream等指令定义。
- fail_timeout=time:指定服务器不可用的尝试时间范围。默认情况下,该参数设置为10s。
- backup:将服务器标记为备份服务器,当主服务器全部不可用时,才传递请求。
此参数不能和hash,ip_hash和random负载均衡方法一起使用。 - down:标记服务器为离线状态。
hash
语法:hash key [consitent]; 指定服务器组的负载均衡方法。客户端-服务器的映射是基于散列key值。key中可以使用nginx变量。如果指定consistent将使用一致性hash方法,可确保将服务器添加到组中或从组中删除服务器时,只有少量的key被重新映射到不同服务器。
注意:从组中添加或删除服务器,可能会导致key值重新映射到其他服务器。
ip_hash
语法:ip_hash;
指定服务器组的负载均衡方法,它是基于客户端ip在服务器间分配请求。注意:1.如果其中一台服务器需要临时删除,需使用down参数标记该服务器,以保留客户端ip地址的当前哈希值。2.在运营商移动网络下,ip经常是会变化的。
keepalive指令
语法:keepalive connections;
每个 worker 进程连接上游服务器的最大长连接数(默认情况下是短连接)。超过此数量时,将关闭最近最少使用的连接。
对于HTTP,应将 proxy_http_version指令设置为“1.1”,并清除 “Connection” 头字段:
upstream http_backend {
server 127.0.0.1:8080;
keepalive 16;
}
server {
location /api/ {
proxy_pass http://http_backend;
proxy_http_version 1.1;
#即使客户端和代理服务器使用的是短链接,代理服务器和上游服务器之间也将使用长连接。
proxy_set_header Connection "";
...
}
}
和它一起使用的还有两个参数,分别是:
- keepalive_requests:设置通过一个keepalive连接可以处理的最大请求数。
- keepalive_timeout 空闲keepalive保持打开的超时时间。
注意:对于fastcgi服务器,需要开启fastcgi_keep_conn才能使keepalive连接正常工作。
last_conn
指定服务器组的负载均衡方法,将请求传递到活动连接数最少的服务器,同时需要考虑权重。如果有多个这样的服务器,就使用轮询的方法。
random
语法:random [two [method]]; 指定服务器组的负载均衡方法,其中将请求随机传递到选择的服务器,同时需要考虑服务器权重。
resolver
语法:resolver address ... [valid=time] [ipv6=on|off] [status_zone=zone]; 配置用于解析上游服务器名的域名解析服务器。
变量
upstream模块支持以下变量:
- $upstream_addr:上游服务器的ip和端口活着UNIX套接字的路径。
- $upstream_bytes_received:从上游服务器中收到的字节数。
- $upstream_bytes_send:发送到上游服务器的字节数。
- $upstream_connect_time:与上游服务器建立连接的时间。
- $upstream_cookie_name:上游服务器在“Set-Cookie”响应头字段中发送的具有指定值的cookie。
- $upstream_header_time:从上游服务器接收header耗费的时间。
- $upstream_response_length:从上游服务器接收响应的长度(bytes)。
- $upstream_response_time:接收上游服务器接收响应耗费的时间。
- $upstream_status:上游服务器的响应状态。
7.nginx反向代理
默认情况下proxy模块默认是启用的,通过该模块能够将客户端的HTTP请求转发到后端服务器。 注意:如无特殊说明,指令的作用域都为:http,server,location。
示例:
location / {
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
模块指令
下面简要介绍几个主要指令,其他指令用是可以查看官方文档。注意:如无特殊说明该模块指令作用域为:http、server、location
主要指令
proxy_pass:指定转发给后端服务器的协议和地址。
语法:proxy_pass 协议://地址[/URI];
协议可以是http或https。地址可以是TCP套接字(域名或者ip地址+port)、UNIX域套接字,还可以指向upstream区段。URI是可选部分,如果指定了URI,location 后面指定的路径将被替换。
作用域:location, location中的if
proxy_pass http://localhost:8080;
proxy_pass http://127.0.0.1:8080;
proxy_pass http://unix:/tmp/backend.sock;
proxy_pass https://192.168.0.1;
proxy_pass http://localhost:8080/uri/;
proxy_pass http://unix:/tmp/backend.sock:/uri/:
# URL中还可以使用变量
proxy_pass http://$server_name:8080;
#指向upstream区段
#格式:proxy_pass http://myblock;
upstream backend {
server 127.0.0.1:8080;
server 127.0.0.1:8081;
}
location ~ \.php($|/) {
fastcgi_pass http://backend;
}
注意:如果proxy_pass指定了URI,那么location匹配不能使用正则表达式。如果代理的URI需要使用正则表达式,则可以使用rewrite和proxy_pass结合的方式来定义转发路径。此时proxy_pass 后面定义的URL不再生效。
location /static_js/ {
rewrite /static_js/(._)$ /$1 break;
proxy_pass http://js.test.com;
}
proxy_next_upstream:指定哪种情况将请求传递到下一个服务器。
语法:proxy_next_upstream error | timeout | invalid_header | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | http_429 | non_idempotent | off ...;
默认:proxy_next_upstream error timeout;
参数说明:
- error:与服务器建立连接或传递请求或读取响应头时发生错误。
- timeout:与服务器建立连接或传递请求或读取响应头时发生超时。
- invalid_header:后端服务器返回空或无效的响应
- http_xxx:发生对应HTTP错误。
- off:禁止将请求传递到下一个服务器。
proxy_next_upstream error timeout http_504;
proxy_ignore_headers:禁用来自后端服务器的某些响应头字段。可以忽略以下字段:X-Accel-Redirect、Expires、Cache-Control、Set-Cookie和Vary。
proxy_set_body:用于重新定义传递给后端服务器的请求正文,一般用于调试目的。
proxy_set_header:用于重新定义或增加传递给后端服务器的请求头字段。 语法:proxy_set_header field value; 默认值:proxy_set_header Host $proxy_host; proxy_set_header Connection close;
除以上外还有proxy_method、proxy_hide_header、proxy_pass_header、proxy_pass_request_body、proxy_pass_request_header、proxy_redirect等指令。
缓冲、缓存和临时文件
proxy_buffer_size:设置缓冲区大小,该缓冲区用于存放来自后端服务器响应数据的开始不分。默认情况下,缓冲区的大小等于一个内存页(根据平台不同,4k或8k)
porxy_buffering:定义是否缓冲后端服务器的响应,如果禁用,响应就直接转发给客户端。
语法:proxy_buffering on | off;
默认:proxy_buffering on;
proxy_buffers :设置缓冲区数量和大小,用于存放从后端服务器读取的响应数据。默认情况下,缓冲区的大小等于一个内存页。
语法:proxy_buffers number size;
默认:proxy_buffers 8 4k | 8k;
proxy_busy_buffers_size:在缓冲区中,收到后端服务器数据总大小超过该指令指定大小时,缓冲区就会被刷新,并且数据被发送到客户端。默认为2*proxy_buffer_size。
默认值:proxy_busy_buffers_size 8k | 16k;
proxy_cache_前缀开头的指令:用于定义存放缓存文件目录等。
例如:proxy_cache、proxy_cache_key、proxy_cache_path等。
超时、错误及限制
proxy_connect_timeout:定义连接到后端服务器的超时时间。
默认:proxy_connect_timeout 60s;
proxy_read_timeout:定义从后端服务器读取数据的超时时间,超时设置仅表示在两个连续的读操作之间,而不是整个响应的传输。如果上游服务器未传输任何内容,则连接被关闭。
默认:proxy_read_timeout 60s;
proxy_send_timeout:定义从发送数据到后端服务器的超时时间,超时设置仅表示在两个连续写操作之间,而不是整个请求的传输。如果后端服务器在这期间未收到任何数据,则连接被关闭。
默认:proxy_send_timeout 60s;
proxy_ignore_client_abort:确定当客户端关闭和代理服务器间的连接时,是否关闭与后端服务器的连接。 默认值:proxy_ignore_client_abort off;
除此之外还有proxy_intercept_errors、proxy_send_lowat、 proxy_headers_hash_max_size、proxy_headers_hash_bucket_size、proxy_store、proxy_store_access等指令等指令。
变量
- $proxy_host:当前请求后端服务器的名称;
- $proxy_port:当前请求后端服务器的端口。
- $proxy_add_x_forwarded_for:该变量包含“X-Forwarded-For”请求头的值,后跟远程客户端的ip地址,这两个值由逗号分割,如果客户端请求头中不存在“X-Forwarded-For”字段,则该变量等于$remote_addr的值。
8.扩展阅读
nginx 官方文档:https://nginx.org/en/docs/