nginx反向代理功能使用(一)

2015-06-02_234938fanxiangdaili 这里使用的是下载好的rpm包,非yum源安装的。 ngxin-1.6.2-1.e16.ngx.x86_64.rpm rpm -q --scripts nginx查看nginx的安装前脚本安装后的脚本 [cc lang="php"] Mode ngx_http_proxy_module ngx_http_upstream_module [/cc] . server{ listn servername location /{ proxy_pass 转交http:linuxea.com:8000 } } . 请求报文从客户端到服务器:reverse proxy 到达nginx拆除报文,匹配location,构建报文送达后端 1.案例1: nginx反向代理:映射 在node2(172.16.249.69)上安装httpd,并且在/var/www/html下创建index.html文件 httpd.con.node2,而后启动httpd 在node1(172.16.249.151)安装nginx,打开配置文件 # vim default.conf 找到location,注释掉root,添加proxy_pass location / { # root /usr/share/nginx/html; proxy_pass http://172.16.249.69/; index index.html index.htm; 保存退出,重启nginx,node1上使用浏览器访问172.16.249.151跳转至172.16.249.69 在node2查看访问日志 . # tail /var/log/httpd/access_log |grep 172.16.249.151 172.16.249.151 - - [02/Jun/2015:17:06:00 +0800] "GET / HTTP/1.1" 200 27 "-" "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" 172.16.249.151 - - [02/Jun/2015:17:13:17 +0800] "GET / HTTP/1.0" 200 27 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C; .NET4.0E; InfoPath.3)" 172.16.249.151 - - [02/Jun/2015:17:13:19 +0800] "GET / HTTP/1.0" 304 - "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C; .NET4.0E; InfoPath.3)" . [root@node2 html]# 2,案例2:虚拟目录代理 在node2上/var/www/html/创建bbs,在bbs文件夹中创建index.html文件,内容:httpd.bbs.com.node2 在node1修改配置文件default.conf,注释案例1中的proxy,添加 location /bbs/ { proxy_pass http://172.16.249.69/bbs/; } 这里不得不说的是,location /bbs/ 这里的bbs可以更改成任意的内容,但是访问的仍然是proxy_pass定义的路径映射。我将bbs换成bsb,访问路径http://172.16.249.69/bsb,访问内容仍然是http://172.16.249.69/bbs/ . location /bsb/ { proxy_pass http://172.16.249.69/bbs/; } . 我将 proxy_pass http://172.16.249.69/bbs/去掉,访问http://172.16.249.69/bbs/得到的内容就是根文件的html/index.html; . location /bbs/ { proxy_pass http://172.16.249.69/; } . 如下: . # vim default.conf location / { root /usr/share/nginx/html; # proxy_pass http://172.16.249.69/; index index.html index.htm; } . . error_page 404 /404.html; location = /404.html { root /usr/share/nginx/html; } location /bbs/ { proxy_pass http://172.16.249.69/bbs/; } . 在node2上查看日志 . # tail /var/log/httpd/access_log | grep bbs 172.16.249.151 - - [02/Jun/2015:17:26:51 +0800] "GET /bbs/ HTTP/1.0" 304 - "-" "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)" 172.16.249.151 - - [02/Jun/2015:17:26:51 +0800] "GET /bbs/ HTTP/1.0" 304 - "-" "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)" . 3,正规表达式 在前端服务器上node1 只要用户访问以jpg|png|gif结尾的文件,都将他代理至172.16.249.69,这里的jpg|png|gif是模式匹配,在这里的proxy_pass http://172.16.249.69后面是不能加任何url的,否则就是语法错误! . location ~* .(jpg|png|gif)$ { proxy_pass http://172.16.249.69; } . 在后node2的/var/www/html/创建images文件夹,从http://172.16.249.69/images/任何图片访问都是没有问题的,当然,不创建images,直接将图片放置根目录也是可以访问的。 4,如果有url重写,向后端代理,是重写后的结果向后端代理。 比如,用户请求的是.mp3,统统请求为wmv文件,在处理过程是不考虑前端的url的,只考虑重写后的url. 5,显示客户端真正的iP地址:proxy_set_header 在前端node1上定义 . proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; . 将内容写进default.conf中,如下所示: . location /bbs/ { proxy_pass http://172.16.249.69/bbs/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location ~* .(jpg|png|gif)$ { proxy_pass http://172.16.249.69; proxy_set_header X-Real-IP $remote_addr; } . 定义完成,重启服务! 在后端node2服务器,修改配置文件,修改内容为:"%{X-Real-IP}i #vim /etc/httpd/conf/http.conf . LogFormat "%{X-Real-IP}i %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i"" combined LogFormat "%h %l %u %t "%r" %>s %b" common LogFormat "%{Referer}i -> %U" referer LogFormat "%{User-agent}i" agent . 通过网页访问,查看tail /var/log/httpd/access_log | grep bbs 现在显示的ip地址便是客户端真实的ip地址。 6,代理缓存加速 值在硬盘,键值加速文件查找速度 在代理缓存中,缓存键值存储,键在内存,内存缓存指向磁盘空间中对应内容的路径,目录也为文件系统结构,1级子目录下做多个缓存子目录,2级子目录,最多不超过三层。1级子目录个数 如: 定义路径指定proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=one:10m; 1表示每个1级目录的名字只能用一个字符 2表示每个二级子目录的名字只能用2个字符 缓存修剪: 当客户端访问url,首先寻找缓存中内容,而不是直接访问后端主机,恰巧后端主机的资源被修改,缓存的内容没过期,那么客户端则无法访问到最新的资源。 当后端资源变更时,缓存不能快速更新,客户端访问到缓存中时,使用特殊的请求:访问到哪些资源便删除哪些资源而后在缓存,这是种特殊请求,也成为缓存修建方法。 proxy_cache_revalidate:过期后重新校验 proxy_cache_valid :自定义缓存时间 示例: 定义缓存:node1 . #vim /etc/nginx/nginx.conf proxy_cache_path /cache/nginx/ levels=1:1 keys_zone=mark:32m; # mkdir -pv /cache/nginx mkdir: created directory `/cache' mkdir: created directory `/cache/nginx # chown -R nginx.nginx /cache/nginx/ #vim /etc/nginx/conf.d/default.conf location /bbs/ { proxy_cache mark; proxy_cache_valid 200 1d; proxy_cache_valid 301 302 10m; proxy_cache_valid any 1m; proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504; proxy_pass http://172.16.249.69/bbs/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location ~* .(jpg|png|gif)$ { proxy_cache mark; proxy_cache_valid 200 1d; proxy_cache_valid 301 302 10m; proxy_cache_valid any 1m; proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504; proxy_pass http://172.16.249.69; proxy_set_header X-Real-IP $remote_addr; } #service nginx configtest #service nginx reload [root@node1 ~]# cd /cache/nginx/ [root@node1 nginx]# ls [root@node1 nginx]# ls 5 [root@node1 nginx]# ls 4 5 c [root@node1 nginx]# . 在node2模拟后端主机资源变更 修改/var/www/html/bbs/index.html 改为httpd.bbs.com.node2.org 这时候在前端代理访问,它还是会显示httpd.bbs.com.node2 在node1上先将缓存删掉测试,测试结果httpd.bbs.com.node2.org 7,把多个主机组成一个组 启动node3节点 配置一个主页页面在/var/www/html/index.html #service httpd start 返回到node1配置 先定义组 #vim /etc/nginx/httpd.conf 在缓存配置下定义(定义这里好看,也好找) . upstream markserver{ server 172.16.249.99; server 172.16.249.69; } .. 在指明组 . # vim /etc/nginx/conf.d/default.conf location /bbs/ { #proxy_cache mark; #proxy_cache_valid 200 1d; #proxy_cache_valid 301 302 10m; #proxy_cache_valid any 1m; #proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504; proxy_pass http://markserver/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location ~* .(jpg|png|gif)$ { #proxy_cache mark; #proxy_cache_valid 200 1d; #proxy_cache_valid 301 302 10m; #proxy_cache_valid any 1m; #proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504; proxy_pass http://markserver; proxy_set_header X-Real-IP $remote_addr; } . :.,$s@[:space:]*proxy_cache@#&@g 语法检查 . # service nginx configtest nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful # service nginx reload Reloading nginx: [ OK ] . 重启后刷新172,16.249,151/bbs,就会形成轮训页面 8,定义权重,加权轮训 node1上定义 . #vim /etc/nginx/http.conf upstream markserver{ server 172.16.249.99 weight=2; server 172.16.249.69; . 9,定义其他调度方法 node1上定义 来自同一个客户端的生成一个哈希码,来自同一个客户端的调度至同一个服务器,不同的客户端调度至不同的上游服务器 . #vim /etc/nginx/http.conf upstream markserver{ ip_hash; server 172.16.249.99; server 172.16.249.69; } . 10,健康监测 node1上定义 . #vim /etc/nginx/http.conf upstream markserver{ server 172.16.249.99 max_fails=2 fail_timeout=1; server 172.16.249.69 max_fails=2 fail_timeout=1; } . 我将node2的httpd手动关闭,形成故障后,将不会在把node2进行轮训了,当把node2开启后就恢复正常。 11,down ip-hash / backup 当我们遇到后端服务器需要更新,但是又不支持频发升级,这时候我们就可以手动标记下线一些服务器进行升级。 在node1上 . #vim /etc/nginx/http.conf 标记node2为backup,就可以下线了。 upstream markserver{ server 172.16.249.99 max_fails=2 fail_timeout=1; server 172.16.249.69 max_fails=2 fail_timeout=1backup; } . 这是就可以对node2进行更新了,更新完成后,在去掉backup 当node2标记为backup时候,通过代理172.16.249.151是访问不了node2的。同时,如果node1忽然意外宕机,node2是可以复活的。备胎的作用凸显无疑,当然,如果还存在任何一个没有标记备胎的buckup,node2还是备胎,node2不通过手动去掉backup,node2永远不会上线。类似于lvs中的backup server.