上篇博文介绍了Nginx的做为http服务器的配置,下面介绍下Nginx的反向代理配置。
ngx_http_proxy_module
1.proxy_pass URL;
上下文:location, if in location, limit_except
proxy_pass后面的路径不带uri时,其会将location的uri传递给后端主机;
location /uri/ {
proxy_pass http://HOST;
}
proxy_pass后面路径是一个uri时,其会将location的uri替换为proxy_pass后端主机的uri;
location /uri/ {
proxy_pass http://HOST/new_uri/;
}
如果location定义其uri时使用了正则表达模式匹配机制,则proxy_pass后的路径必须不能使用uri;
location ~|~* PATTERN {
proxy_pass http://HOST;
}
http://www.magedu.com/bbs/ --> http://172.16.100.7/bbs/
http://www.magedu.com/bbs/ --> http://172.16.100.7/
示例1.当后端定义为主机不加URL时,直接转到服务器上location对应URL上:
location / { index index.html; proxy_pass http://172.18.29.140; } # curl http://172.18.29.142/index.html
示例2.当后端定义为主机加URL时,重写location对应URL到后端:
location / { index index.html; proxy_pass http://172.18.29.140/admin/; } # curl http://172.18.29.142/index.html admin index page @server140
示例3.location匹配正则时,proxy_pass 指定后端主机不能添加uri;
location ~/.*\\.jpg { index index.html; proxy_pass http://172.18.29.140; } # curl -I http://172.18.29.142/1.jpg HTTP/1.1 200 OK Server: nginx/1.0.15 Date: Thu, 19 May 2016 07:42:41 GMT Content-Type: p_w_picpath/jpeg Connection: keep-alive Content-Length: 931957 Last-Modified: Wed, 11 May 2016 07:55:14 GMT Accept-Ranges: bytes
示例4.这里视图为后端主机添加URL时,产生错误,就如上所说;看起来很不方便,实际上若要求需要在后端主机建立对应路径映射的虚拟主机才行!
location ~/.*\\.jpg { index index.html; proxy_pass http://172.18.29.140/; } # nginx -t nginx: [emerg] "proxy_pass" may not have URI part in location given by regular expression, or inside named location, or inside the "if" statement, or inside the "limit_except" block in /etc/nginx/nginx.conf:22 nginx: configuration file /etc/nginx/nginx.conf test failed
2.proxy_set_header
可用于上下文:http
, server
, location
proxy_set_header field value;
设定向后端主机发送的请求报文的首部及其值;
示例:
将远端客户端IP地址添加到报文首部,传递给后端主机;
proxy_set_header X-Real-IP $remote_addr;
将真正的请求客户端地址放置在X-Forwarded-For中传递到后端服务器,效果和前者一样。
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
在修改之前,后端主机记录都是代理服务器地址,为了统计访问行为,这里需要修改:
# 这里从140服务器上访问http://172.18.29.142/1.jpg,之前的日志: 172.18.29.142 - - [25/May/2016:21:15:42 +0800] "HEAD /1.jpg HTTP/1.0" 200 - "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.15.3 zlib/1.2.3 libidn/1.18 libssh2/1.4.2" # 添加报文首部,并修改后端日志记录格式 ## 代理添加报头,可以在http,server,location中使用 proxy_set_header X-Forward-For $proxy_add_x_forwarded_for; ## 修改后端主机日志格式,这里时httpd的日志,生产中一般也是如此; LogFormat "%{X-Forward-For}i %l %u %t \\"%r\\" %>s %b \\"%{Referer}i\\" \\"%{User-Agent}i\\"" combined #tail /var/log/http/access.log 172.18.29.140 - - [25/May/2016:21:21:18 +0800] "HEAD /1.jpg HTTP/1.0" 200 - "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.15.3 zlib/1.2.3 libidn/1.18 libssh2/1.4.2" ## 可以看到这显示真实请求主机的地址
缓存相关的选项(缓存要先定义,后调用)
1.proxy_cache_path
proxy_cache_path path [levels=levels] keys_zone=name:size [inactive=time] [max_size=size] ;
用于http上下文 ,定义一个代理缓存路径,也称为zone;
2.proxy_cache ZONE | off;
调用缓存,默认为off;ZONE指代缓存路径。
3.proxy_cache_key string;
定义缓存键;
proxy_cache_key $request_uri
proxy_cache_key $scheme$proxy_host$request_uri
4.proxy_cache_valid [code ...] time
为不同的响应码设定其缓存的时长;
示例:
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
5.proxy_cache_use_stale
proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | off ...;
当于后端主机链接出错时,决定什么时候失效的缓存是可用来响应的
proxy_cache_path /var/cache/nginx/proxy_cache levels=2:1 keys_zone=proxy:1m;
server {
....
location / {
# root html;
proxy_pass http://172.18.29.140/admin/;
index index.html index.htm;
proxy_cache proxy;
proxy_cache_key $request_uri;
proxy_cache_valid 200 10m;
}
示例:使用代理缓存
http { include mime.types; default_type application/octet-stream; proxy_cache_path /var/cache/nginx/proxy_cache levels=2:1 keys_zone=http:1m inactive=1h max_size=100m; server { proxy_cache http; proxy_cache_valid 200 302 10m; proxy_cache_key $request_uri; proxy_set_header X-Forward-For $proxy_add_x_forwarded_for; listen 172.18.29.142:80; server_name www.magedu.com; root /data/webs/v1; index index.html; location / { proxy_pass http://172.18.29.141; } ... ... }
请求http://172.18.29.142/index.html后查看缓存为位置:
# pwd /var/cache/nginx/proxy_cache # ll total 8 drwx------ 3 nginx nginx 4096 May 19 16:52 a4 drwx------ 3 nginx nginx 4096 May 19 16:52 d9
ngx_http_headers_module
用于在响应给客户端的报文中添加首部;
(1) add_header name value [always];
上下文:http, server, location, if in location
向响应报文添加自定义首部,并赋值;
add_header X-Via $server_addr;
如果指定always那么就是所有状态都添加该header,默认为200+ 300+ 部分添加。
示例:在响应报文中添加代理主机IP报文首部
http{ ... add_header X-Via $server_addr; ... } # curl -I http://172.18.29.142/ HTTP/1.1 200 OK Server: nginx/1.0.15 Date: Thu, 19 May 2016 09:03:05 GMT Content-Type: text/html; charset=UTF-8 Connection: keep-alive Last-Modified: Tue, 24 May 2016 02:30:07 GMT ETag: "e0fae-14-5338d55e359cd" Content-Length: 20 X-Via: 172.18.29.142 Accept-Ranges: bytes # 可以看到X-Via首部
ngx_http_upstream_module
将多个后端主机定义为服务器组,而后可由proxy_pass, fastcgi_pass, memcached_pass等进行引用;调用方式如:
prioxy_pass http://webs
(1) upstream name { ... }
定义后端服务器组;引入新的上下文;只能用于http上下文;
name:名称,直接字符串;
(2) server
server address [parameters];
定义服务器的地址和相关的参数;
地址格式:
IP[:port]
HOSTNAME[:port]
unix:/PATH/TO/SOME_SOCK_FILE
参数:
weight=number:服务器权重;
max_fails=number:最大失败尝试次数;
fail_timeout=time:设置服务器不可用超时时长;
backup:备用主机;
down:手动标记其不再处理任何用户请求;
upstream backend {
ip_hash;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com down;
server backend4.example.com;
}
(3) ip_hash;
源地址哈希调度算法;
(4) least_conn;
最少连接调度算法;
(5) health_check [parameters]; (仅仅2.0版本支持)
定义后端主机的健康状态检测机制;只能用于location上下文;
可用参数:
interval=#:检测的频度,默认为5秒;
fails=number:判定为失败的检测次数;
passes=number:判定为成功的检测次数;
uri=uri:执行健康状态检测时请求的uri;
match=name:基于哪个match做检测结果为“成功”或“失败”的判定;
port=number:向服务器的哪个端口发起健康状态检测请求;
说明:health_check 参数中指定其他端口,健康状态检测可能不希望被记录到日志中,可以设置另外一个虚拟主机上
(6) match name { ... }
仅能用于http上下文 ;对后端主机做健康状态检测时,定义其结果判断标准;
专用指令:
status:期望的响应码;
status CODE
status ! CODE
status CODE-CODE
header:基于响应首部进行判断
header HEADER=VALUE
header HEADER!=VALUE
header [!] HEADER
header HEADER ~ VALUE
body:期望的响应报文的主体部分应该有的内容;
body ~ "CONTENT"
body !~ "CONTENT"
(7) hash key [consistent];
定义调度方法,可自定义基于何种信息(key)进行绑定;
hash $remote_addr
hash $request_uri
hash $cookie_username
hash key 可以根据某个字段哈希绑定到固定服务器,其中目标uri可以放置在nginx调度缓存服务器时使用:访问同一个页面都会指定到某个固定服务器上。
upstream websrv { ip_hash; server 172.18.29.141:80 max_fails=3; server 172.18.29.140:80; } 访问 该主机将不会再次被调度到down的主机。所以nginx做负载均衡时,可以很平滑的处理,不影响线上。 match name { ... } 仅能用于http上下文 ;对后端主机做健康状态检测时,定义其结果判断标准; 专用指令: status:期望的响应码; status CODE status ! CODE status CODE-CODE header:基于响应首部进行判断 header HEADER=VALUE header HEADER!=VALUE header [!] HEADER header HEADER ~ VALUE body:期望的响应报文的主体部分应该有的内容; body ~ "CONTENT" body !~ "CONTENT"