Nginx ngx_http_proxy_module反向代理

正向代理


比如, 你买束花, 想要给隔壁工位的测试妹子小丽表白. 但是又怕被人家直面拒绝太没面子. 于是你把鲜花委托给平时和小丽一起的测试小伙伴小红. 让她帮忙把花送给小丽. 这就是一个简单的代理过程, 小红作为代理帮你把花送给了小丽, 当然这种情况在现实中并不推荐使用, 因为难以避免中间商赚差价,哈哈。

在上面的例子中, 你作为客户端(请求方), 想要向服务方(小丽)发起请求. 但是碍于面子你主动找到了第三方(小红)作为代理向服务方发送请求, 这种情况就是常说的正向代理. 正向代理在互联网中的使用主要是科学上网, 你想访问guge但是碍于防火墙你只能通过v  p  n服务器作为代理才能访问. 这个时候一般也要找值得信赖的v  p  n厂商, 避免中间商赚差价。

 

 

反向代理


关于反向代理的例子, 那就比较多啦. 比如, 孤独的你躺在床上夜不能寐. 于是乎, 拿出手机, 点亮了屏幕, 拨通 10086, 中国移动就会随机分配一个当前处于空闲的客服MM, 你可以和客服MM聊聊天, 问问她家住哪里, 有没有男朋友, 她的微信号, 她的手机号, 星座, 八字.......

在这个例子中, 中国移动就充当了反向代理的角色. 你只需要拨打 10086. 至于会不会分配到 MM 会分配到哪个 MM 在接通之前你都是不知道的. 反向代理在互联网中的使用主要是实现负载均衡. 当你访问某个网站的时候, 反向代理服务器会从当前网站的所有服务器中选择一个空闲的服务器为你响应. 用于均衡每台服务器的负载率

反向代理是nginx的一个重要功能,在编译安装时会默认编译该模块。在配置文件中主要配置proxy_pass指令。代理服务器接受客户端的请求,然后把请求代理给后端真实服务器进行处理,然后再将服务器的响应结果返给客户端。

 

反向代理的优点


1)保护服务安全

  • 隐藏服务节点的IP;
  • 将服务节点置于防火墙之后,避免直接攻击业务节点服务器。

2)服务节点更专注于业务,同时提升性能

  • 由于有反向代理的存在,可以让反向代理服务器去实现比如https、gzip压缩等与业务无关的功能;
  • 提供动静态分离,将静态文件发往静态服务器或本地文件系统,避免业务节点处理这些与业务无关的请求;
  • 提供缓存机制,将一些短时间内不会变化的动态内容,在反向代理服务器这层增加缓存,降低业务服务器的请求量;
  • 由于控制权在代理服务这边,完全可以根据服务节点的性能动态分配请求,做到服务节点性能最佳。

正是由于Ngxin引入了反向代理的特性,让请求和响应都要经过Nginx,因此给Nginx带来了非常多的可能。比如负载均衡、HTTP缓存等。

 

反向代理语法


代理服务器的协议,可支持http与https,地址可以指定为域名或IP地址,以及可选端口。

例如:

Syntax: proxy_pass URL;

Default: —

Context: location, if in location, limit_except

proxy_pass http://localhost:9000/uri/;

proxy_pass http://192.168.0.188:8080;

proxy_pass http://192.168.0.188;

反向代理示例几则


实例一:location和proxy_pass都不带uri路径 

192.168.179.99代理服务器  192.168.179.100后端服务器   192.178.179.101客户端

192.168.179.99代理服务器
[root@www vhost]# vim /usr/local/nginx/conf/vhost/www.test.com.conf --当访问www.test.com
    server {
        listen    192.168.179.99:80;
        server_name  www.test.com;
        charset utf-8;
          root  /data/www/test1;
          location /{
           proxy_pass http://192.168.179.100;  --代理给后端服务器192.168.179.100
           }
     }


192.168.179.100 后端服务器
server{
      listen  80;
      server_name localhost;
      charset utf-8;
      location =/{
      index index.html;  
     }
}
[root@www ~]# echo "proxy this is 192.168.179.100 page" > /usr/local/nginx/html/index.html --在后端服务器主页面显示proxy this is 192.168.179.100 page
[root@www ~]# curl localhost
proxy this is 192.168.179.100 page


客户端192.168.179.101访问后端192.168.179.100资源的两种方法
(1)不通过代理,客户端直接访问后端192.168.179.100上的资源
[root@www ~]# curl 192.168.179.100/index.html
proxy this is 192.168.179.100 page

(2)客户端通过代理服务器192.168.179.99访问192.168.179.100的资源
[root@www ~]# curl 192.168.179.99/index.html  --可以看到访问的是179.99的页面却拿到的是179.100的页面资源,对于客户端压根感觉不到179.100的存在,所以说后端的服务器对于我们来说是屏蔽的,只能感觉到代理服务器的存在
proxy this is 192.168.179.100 page

[root@www ~]# tail -f /usr/local/nginx/logs/access.log   --可以看到后端服务器压根不知道客户端的IP信息,只能得到代理服务器的信息
192.168.179.99 - - [15/Mar/2020:22:23:25 +0800] "GET /index.html HTTP/1.0" 200 35 "-" "curl/7.29.0"

 

实例二:proxy_pass没有设置uri路径,但是代理服务器的location 有uri,那么代理服务器将把客户端请求的地址传递给后端服务器

192.168.179.99代理服务器

   server {

        listen    192.168.179.99:80;

        server_name  www.test.com;

        charset utf-8;

        root /data/www/test;

        location /document/data/{   --这里请求的路径会追加到后端root路径后

           proxy_pass http://192.168.179.100;

           }

     }



192.168.179.100后端服务器

server{

      listen  80;

      server_name localhost;

      charset utf-8;

error_page 404 =200 /404.html;

      location =/{

      index index.html;  

     }

}

[root@www ~]# mkdir -p /usr/local/nginx/html/document/data/

[root@www ~]#
echo "proxy this is 192.168.179. 100 /usr/local/nginx/html/document/data/index.html" > /usr/local/nginx/html/document/data/index.html



192.168.179.101客户端访问

[root@www ~]# curl 192.168.179.99/document/data/index.html

proxy this is 192.168.179. 100 /usr/local/nginx/html/document/data/index.html

可以看到,完整请求路径是在后端服务器的root路径/usr/local/nginx/html 后追加客户端请求的路径/document/data/


实例三:如果proxy_pass设置了uri路径,则需要注意,此时,proxy_pass指令所指定的uri会覆盖location的uri。


192.168.179.99代理服务器(/img路径会覆盖/document/data路径)
  server {
        listen    192.168.179.99:80;
        server_name  www.test.com;
        charset utf-8;
          root /data/www/test;
          location /document/data/{
           proxy_pass http://192.168.179.100/img/;
           }
     }
        

192.168.179.100后端服务器
服务端是创建/usr/local/nginx/html/img 还是创建/usr/local/nginx/html/img/document/data??
server{
      listen  80;
      server_name localhost;
      charset utf-8;
      location /{
      root html;
      index index.html;
     }
}
[root@www ~]# mkdir -p /usr/local/nginx/html/img
[root@www ~]# echo "proxy this is 192.168.179.100  /usr/local/nginx/html/img/index.html" > /usr/local/nginx/html/img/index.html 


192.168.179.101 客户端访问
[root@www ~]# curl 192.168.179.99/document/data/index.html
proxy this is 192.168.179.100  /usr/local/nginx/html/img/index.html
可以看到如果 proxy_pass 指定了uri路径,与location的uri /document/data/ 就失效了,就不再参考location的uri了。

 

获取远程客户端真实ip地址(我们并不关心代理服务器的IP,我们关心的是客户端的IP)


因为后端的服务器只知道代理服务器的信息,并不知道客户端的信息,客户端和服务端中间隔着代理服务器。有些服务端需要知道客户端真实的IP,那么这就需要代理服务器将客户端的信息给到后端了

192.168.179.99代理服务器
    server {
        listen    192.168.179.99:80;
        server_name  www.test.com;
        charset utf-8;
          root /data/www/test;
          location /document/data/{
           proxy_pass http://192.168.179.100/img/;
           proxy_set_header Host $host;
           proxy_set_header X-Real-IP $remote_addr;
           }
     }


192.168.179.100后端服务器日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_real_ip"';
access_log logs/access.log main;


192.168.179.101 客户端访问
[root@www ~]#  curl 192.168.179.99/document/data/
proxy this is 192.168.179.100  /usr/local/nginx/html/img/index.html

192.168.179.101后端查看日志信息
(1)通过curl
[root@www ~]# tail -f /usr/local/nginx/logs/access.log --查看后端服务器日志信息
192.168.179.99 - - [21/Mar/2020:10:06:24 +0800] "GET /img/hh.html HTTP/1.0" 200 26 "-" "curl/7.29.0" "192.168.179.101"  --可以看到日志里面记录了远程客户端的真实IP192.168.179.101

(2)通过浏览器 中输入www.test.com/document/data/ 访问是如下日志
192.168.179.99 - - [21/Mar/2020:10:11:17 +0800] "GET /img/hh.html HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36" "192.168.179.4"
发布了289 篇原创文章 · 获赞 323 · 访问量 39万+

猜你喜欢

转载自blog.csdn.net/qq_34556414/article/details/104954341