上篇博文介绍了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

可用于上下文:httpserverlocation

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"