引用網址:http://www.jianshu.com/p/374c938a9915
这两天读了读Nginx的官方文档,记个笔记。
启动nginx
/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
./nginx
Starting, Stopping, and Reloading Configuration
nginx -s signal
stop -> fast shutdown
quit -> graceful shutdown
reload -> reloading the configuration file
reopen -> reopening the log files
Unix tools kill
kill -s QUIT 1628
- 找到pid的两个方法
- nginx.pid文件,在
/usr/local/nginx/logs
or/var/run
ps -ax |grep nginx
- nginx.pid文件,在
server context
- context的概念,每行以分号结尾的都是一个指令,大括号套一系列的指令就是context。
- 一个http可以包含多个server。
- server里面listen 表明这个server的端口号。
- root,web的根目录。
- server_name就是host,一个server Context可以配置多个server_name
- 如:
server_name localhost localhost.org;
- 如:
- server_name可以使用通配符,可以使用正则表达式,匹配规则:
- Exact name
- Longest wildcard starting with an asterisk, such as *.example.org
- Longest wildcard ending with an asterisk, such as mail.*
- First matching regular expression (in order of appearance in the configuration file)
- 如果host header不能够匹配任何一个server_name,可以设置default_server来处理它。
- 如:listen 80 default_server;
location
-
location指令有两种不同的参数:
-
前缀字符串(pathnames)
- 那些以该前缀字符串开头的的URIs都会匹配到。
-
如:
location /some/path { ... }
这个会匹配/some/path/test 但是不会匹配 /test/some/path
-
正则表达式
-
大小写敏感的前面加一个~
location ~ \.html? { ... }
这个会匹配url中包含.html或者.htm的,任何位置都可以。
- 大小写不敏感的加~*
-
- 匹配规则,正则表达式拥有的更高的优先级,除非用了^~修饰符。^~ 如果把这个前缀用于一个常规字符串,那么告诉nginx 如果路径匹配那么不测试正则表达式。
- 确切的匹配的逻辑:
- Test the URI against all prefix strings.
- The = (equals sign) modifier defines an exact match of the URI and a prefix string. If the exact match is found, the search stops.
- If the ^~ (caret-tilde) modifier prepends the longest matching prefix string, the regular expressions are not checked.
- Store the longest matching prefix string.
- Test the URI against regular expressions.
- Break on the first matching regular expression and use the corresponding location.
- If no regular expression matches, use the location corresponding to the stored prefix string
-
-
location context中的指令
- root指令来声明访问静态文件的路径,如uri是/images/example.png,如果匹配到的location的root指令的值是/data,那么就会把/data/images/example.png作为响应。
- proxy_pass指令,将请求打到配置的url上,被代理的server的响应到客户端。
-
如:
server { location /images/ { root /data; } location / { proxy_pass http://www.example.com; } }
使用变量
在配置nginx的时候可以使用变量,变量以$开头,变量在运行是得到对应的值,然后作为参数传给指令。有很有预定义的变量,如core HTTP varabiles,可以用set map和geo指令来自定义变量。大多数的变量都是在运行时得到值并且包含与特定请求相关的信息。注意是特定请求不是context。
返回特定的状态码
-
最简单的方式是使用return指令返回特定的状态码。
-
第一个参数是状态码,第二个参数是重定向的url或者返回体中的文字(只限于301、302、303、307)。
location /wrong/url { return 404; } location /permanently/moved/url { return 301 http://www.example.com/moved/here; }
-
url重写
- 通过rewrite指令进行url重写,在server和 location里面都可以使用rewrite指令。
- 一共有三个参数,第一个是匹配url的正则表达式,第二个参数是重写的url,第三个参数是一个标记是可选参数。
- uri可以多次更改,uri会依次匹配每个rewrite指令。
- 第三个参数,last和break的区别
- 两个值在server context中表现一致,跳过剩下的rewrite指令,进行location匹配。
- 在location context中,last会跳出当前location寻找新的location匹配,而break不会再去匹配其他的location,在当前location请求对应的uri。
- 小心循环重定向,尽量在server context里面进行url重写。
-
例子:
-
多个rewrite指令,如果都不匹配返回403
server { ... rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last; rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra last; return 403; ... }
-
循环重定向
location = error.html { rewrite /error.html /error.html last; fastcgi_pass 127.0.0.1:9000; }
-
break
location /users/ { rewrite ^/users/(.*)$ /show?user=$1 break; }
-
handling errors
通过error_page指令,来处理错误。
-
当发生404错误时候,返回一个自定义的页面
error_page 404 /404.html;
-
当发生404的时候,重定向到一个新的url
location /old/path.html { error_page 404 =301 http:/example.com/new/path.html; }
-
内部重定向
-
配置
server { ... location /images/ { # Set the root directory to search for the file root /data/www; # Disable logging of errors related to file existence open_file_cache_errors off; # Make an internal redirect if the file is not found error_page 404 = /fetch$uri; } location /fetch/ { proxy_pass http://backend/; } }
- 如果
/images/some/file
没有找到,它就会被替换成/fetch/images/some/file
,然后寻找新的location,然后再打到被代理的服务器。 open_file_cache_errors
指令用于组织文件找不到时的报错信息,这里就不需要打开了,因为文件找不到时候已经被处理掉了。
-
二
根目录和index文件
- 通过root指令来声明根目录的路径,root指令可以放到http, server或者location的任一层级里。子层级重新定义的root会覆盖父层级的root。
-
例子
server { root /www/data; location / { } location /images/ { } location ~ \.(mp3|mp4) { root /www/media; } }
- 如果一个请求以斜杠结尾,nginx认为它想访问一个目录然后会去寻找index文件,index指令用来定义index文件的名称,默认是index.html。
- 如果index文件不存在会报404,但是如果想列出该目录下的文件,则使用audoindex指令。
- 如:
location /images/ { autoindex on; }
- 如:
- 可以在index指令后面列出不止一个文件名字,中间用空格分开,nginx按顺序查找,然后返回第一个可访问的。
- 为了返回index文件,nginx检测文件是否存在然后将文件名字连接到获取的请求的uri上进行内部重定向。
-
例子
-
配置:
location / { root /data; index index.html index.php; } location ~ \.php { fastcgi_pass localhost:8000; ... }
- 如果请求的uri是/path/并且/data/path/index.html不存在,但是/path/index.php是存在的,它匹配到了第二个location,达到被代理的服务上。
-
Trying Serveral Options
-
try_files 指令检测指定的文件或者目录是否存在,如果不存在进行内部跳转或者返回一个指定的状态码。
-
如:
server { root /www/data; location /images/ { try_files $uri /images/default.gif; } }
- 如果uri所请求的文件不存在就会内部重定向到
/www/data/images/default.gif
。 - 第二个参数也可以是一个指定的状态码。
- 如:
location / { try_files $uri $uri/ $uri.html =404; }
- 如:
-
三
将一个请求打到被代理的服务器
- 在location里面使用proxy_pass指令来指定代理的地址,地址可以包含端口号。
-
例如:
location /some/path/ { proxy_pass http://www.example.com/link/; } location ~ \.php { proxy_pass http://127.0.0.1:8000; }
- 注意下第一个例子,如果代理的地址包含一个uri,/link/。它将会替换请求的uri中匹配location参数的那部分
- 如果请求是/some/path/page.html,uri则会被代理成:
http://www.example.com/link/page.html
。 - 如果代理的地址没有uri,那么将整个uri传递过来。
- 将请求打到非http服务:
fastcgi_pass
把请求打到FastCGI服务器uwsgi_pass
uwsgi服务器scgi_pass
SCGI服务器memcached_pass
memcached 服务器
传递请求头
- 默认的,nginx重新定义两个header,"Host"和"Connection",并且排除掉值为空的header。"Host"的值是$proxy_host变量的值,"Connection"设置成close。
- 使用proxy_set_header来改变header,这个指令可以放到location或者更高的层级,它也可以在特定的server context或者http块中指定。
-
如:
location /some/path/ { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_pass http://localhost:8000; }
-
如果不想让某个header传给被代理的服务器,将其置空。
location /some/path/ { proxy_set_header Accept-Encoding ""; proxy_pass http://localhost:8000; }
选择出口IP
- 代理服务器可能有多个ip地址,对于一个特定的被代理的server可以选择一个特定的ip地址。
- 使用
proxy_bind
来指定ip地址。ip地址也可以使用变量,如$server_addr,指定的是接受请求的那个ip -
例子:
location /app1/ { proxy_bind 127.0.0.1; proxy_pass http://example.com/app1/; } location /app2/ { proxy_bind 127.0.0.2; proxy_pass http://example.com/app2/; } location /app3/ { proxy_bind $server_addr; proxy_pass http://example.com/app3/; }
四
代理一组服务器
-
使用upstream指令来定义一组服务器,指令放在http context里
-
如:
http { upstream backend { server backend1.example.com weight=5; server backend2.example.com; server 192.0.0.1 backup; } }
-
-
使用proxy_pass指令把请求打到被代理的服务器上
-
如:
server { location / { proxy_pass http://backend; } }
-
选择一种负载均衡方法
-
默认的是权重轮询算法,nginx会按照各个server的权重比来分发请求。
-
如:
upstream backend { server backend1.example.com; server backend2.example.com; }
-
-
最少连接法:每次都选择连接数组少的server,如果有多个server的连接数相同,再根据这几个server的权重分发请求。
-
例:
upstream backend { least_conn; server backend1.example.com; server backend2.example.com; }
-
-
ip哈希:使用IPv4的前三个八字节位或者IPv6的全部来计算哈希值,所以相同地址的请求始终会打到相同的Server上,除非这个server不可用。
- 如果一个server需要暂时移除,使用down参数来避免请求打到这台机器上,应该哈希到这台机器上的请求会自动的发送到组里的下一台。
-
如:
upstream backend { ip_hash; server backend1.example.com; server backend2.example.com; server backend3.example.com down; }
-
哈希:使用自定义的key去进行哈希计算。
-
通过consistent参数使用ketama一致哈希算法来减少增减服务器对客户端的影响。
-
例:
upstream backend { hash $request_uri consistent; server backend1.example.com; server backend2.example.com; }
- 上面的就是通过uri进行哈希计算。
-
-
-
最小响应时间:对于每个请求,nginx选择平均等待时间最小并且连接数最少的。
- 通过least_time的参数来确定平均等待时间的计算方式。
- header: Time to receive the first byte from the server
- last_byte: Time to receive the full response from the server
-
如:
upstream backend { least_time header; server backend1.example.com; server backend2.example.com; }
- 通过least_time的参数来确定平均等待时间的计算方式。
服务器权重
- 默认的权重是1,通过weight参数来指定权重值。
- 通过backup来标记备用服务器,如果其他的都宕机了,请求会打到备用的服务器是上。
-
例:
upstream backend { server backend1.example.com weight=5; server backend2.example.com; server 192.0.0.1 backup; }
服务器慢启动
- 对于刚刚恢复的服务器,如果一下子被请求淹没可能会再次宕机。
- 可以通过server指令的slow_start参数来让其权重从0缓慢的恢复到正常值。
-
例:
upstream backend { server backend1.example.com slow_start=30s; server backend2.example.com; server 192.0.0.1 backup; }
- 注意如果一个组里面只有一个server,那么max_fails,fail_timeout和slow_start参数都会被忽略。并且这个服务器永远都不会被认为是不可用的。
Enabling Session Persistence
- Session持久性是指nginx识别客户端的session然后把同一个session的请求路由到同一个server上。
-
nginx支持三种session持久的方法,通过sticky指令去设置。
-
sticky cookie方法。通过这种方法,当server第一个响应的时候,nginx添加一个cookie来标识是哪个server响应的,当它下次请求的时候,会带着cookie,nginx会把请求路由到同一台server。
-
例:
upstream backend { server backend1.example.com; server backend2.example.com; sticky cookie srv_id expires=1h domain=.example.com path=/; }
-
-
sticky_route方法,使用这种方法,nginx第一个收到请求的时候会给客户端下发一个路由。后续的请求都会带着路由参数,nginx再来判断请求该打到哪个server上。路由信息可以通过cookie或者uri获取到。
-
例:
upstream backend { server backend1.example.com route=a; server backend2.example.com route=b; sticky route $route_cookie $route_uri; }
-
- cookie learn 方法。通过这种方法,nginx通过检测请求和响应来寻找session标记。通常,这些标记通过cookie传递。如果一个请求的包含的session标记已经learned,nginx将会把请求打到正确的server上。
-
例:
upstream backend { server backend1.example.com; server backend2.example.com; sticky learn create=$upstream_cookie_examplecookie lookup=$cookie_examplecookie zone=client_sessions:1m timeout=1h; }
- 在这个例子中,server通过在响应中设置一个"EXAMPLECOOKIE"来标记一个session。
- create的参数指定一个变量来指示一个session的创建,在这个例子中,server发送"EXAMPLECOOKIE"表示新的session建立。
- lookup的参数指定如何寻找一个已经存在的session,在这个例子中,通过查找客户端的"EXAMPLECOOKIE"来搜索现有的session。
- zone 指定一块共享的内存来保存sticky sessions的信息。上个例子中,这块空间叫做client_sessions,大小为1M。
-
限制连接数量
- 可以通过max_conns参数来限制连接数,如果达到了最大连接数,请求就可以放到通过queue指令生命的队列中来等待后续的处理 ,queue指令设置了可以放到队列中得最大的请求数、
-
例:
upstream backend { server backend1.example.com max_conns=3; server backend2.example.com; queue 100 timeout=70; }
- 如果队列排满或者在可选参数timeout设置的时间内无法选择上游服务器,客户端将接到一个错误。
- 注意如果闲置的keepalive连接在另一个worker processes中打开了max_conns限制会被忽略。导致的结果是,在多个工作进程共享内存的配置中,连接的总数可能会超过max_conns的值。
被动的健康监测
- 当nginx认为一个server不可用,它会暂时停止向这个server转发请求直至nginx再次认为它是可用的。
- nginx通过两个参数来控制nginx的判断
- fail_timeout,当在fail_timeout时间段内,失败次数达到一定数量则认为该server不可用。并在接下来的fail_timeout时间内不会再将请求打到这个server上。 - max_fails,这个max_fails就是上面说的失败的一定数量。
- 默认的值是10秒和1次尝试。
-
例:
upstream backend { server backend1.example.com; server backend2.example.com max_fails=3 fail_timeout=30s; server backend3.example.com max_fails=2; }
主动的心跳检测
- 使用health_check指令来检测server是否可用,除此之外还要使用zone指令。
-
例:
http { upstream backend { zone backend 64k; server backend1.example.com; server backend2.example.com; server backend3.example.com; server backend4.example.com; } server { location / { proxy_pass http://backend; health_check; } } }
- 在上个例子中,nginx每五秒请求一次backend组里的每台机器,请求地址是"/",如果失败或者超时(或者返回的状态码不是2xx或者3xx),nginx就认为这个server宕机了。nginx将停止向它转发请求,直至其再次通过心跳检测。
- 可以通过参数控制health_check指令的行为。
-
例:
location / { proxy_pass http://backend; health_check interval=10 fails=3 passes=2; }
- 上个例子是每十秒检测一次,如果失败了3次就认为宕机了,如果成功2次就认为通过了检测。
- 也可以检测特定的uri
-
例:
location / { proxy_pass http://backend; health_check uri=/some/path; }
-
通过match块自定义成功的状态。
http { ... match server_ok { status 200-399; body !~ "maintenance mode"; } server { ... location / { proxy_pass http://backend; health_check match=server_ok; } } }
- 上个例子中要求status在200到399之间,并且body满足提供的正则表达式。
-
match块中可以包含一个status的状态,一个body的状态和多个header的状态。
match welcome { status 200; header Content-Type = text/html; body ~ "Welcome to nginx!"; }
-
使用!
match not_redirect { status ! 301-303 307; header ! Refresh; }
- 上个例子表示status不是301、302、303或者307,并且header中不包含Refresh。
至此Nginx笔记结束,了解了这些后,对于看懂一个Nginx的配置,了解Nginx能够实现什么功能和对其进行小改应该会有一定的帮助。
留言列表