nginx服务器反向代理与负载均衡

Nginx反向代理:
一、 反向代理概念:
反向代理是nginx的一个重要功能,在编译安装时会默认编译该模块。在配置文件中主要配置proxy_pass指令。
代理服务器接受客户端的请求,然后把请求代理给后端真实服务器进行处理,然后再将服务器的响应结果返给客户端。
二、反向代理作用:
与正向代理(正向代理主要是代理客户端的请求)相反,反向代理主要是代理服务器返回的数据,所以
它的作用主要有以下两点:
1、 可以防止内部服务器被恶意攻击(内部服务器对客户端不可见)。
2、为负载均衡和动静分离提供技术支持。

环境的准备:

------------------------------------------------------
client:192.168.4.1                   eth0
------------------------------------------------------
proxy: 192.168.4.5                   eth0
nginx  192.168.2.5                   eth1
------------------------------------------------------
web1:192.168.2.100                 eth1
web2:192.168.2.200                 eth1web1:192.168.2.100                 eth1


在web1上安装httpd,创建访问页面。

[root@web1 ~]# cat /var/www/html/
a.html      index.html  
[root@web1 ~]# cat /var/www/html/index.html 
web1:192.168.2.100
[root@web1 ~]# netstat -anptul|grep :80
tcp        0      0 :::80                       :::*                        LISTEN      1761/httpd          
[root@web1 ~]# ps -ef |grep httpd
root      1761     1  0 01:47 ?        00:00:00 /usr/sbin/httpd
apache    1765  1761  0 01:47 ?        00:00:00 /usr/sbin/httpd
apache    1766  1761  0 01:47 ?        00:00:00 /usr/sbin/httpd
apache    1767  1761  0 01:47 ?        00:00:00 /usr/sbin/httpd
apache    1768  1761  0 01:47 ?        00:00:00 /usr/sbin/httpd
apache    1769  1761  0 01:47 ?        00:00:00 /usr/sbin/httpd
apache    1770  1761  0 01:47 ?        00:00:00 /usr/sbin/httpd
apache    1771  1761  0 01:47 ?        00:00:00 /usr/sbin/httpd
apache    1772  1761  0 01:47 ?        00:00:00 /usr/sbin/httpd
root      1896  1872  0 02:17 pts/0    00:00:00 grep httpdweb2:192.168.2.200                 eth1


在web2上安装nginx,创建访问页面。

[root@web2 ~]# cat /usr/local/nginx/html/index.html 
web2:192.168.2.200
[root@web2 ~]# netstat -anptul|grep :80
[root@web2 ~]# /usr/local/nginx/sbin/nginx 
[root@web2 ~]# netstat -anptul|grep :80
tcp        0      0 0.0.0.0:80                  0.0.0.0:*                   LISTEN      1878/nginx          
[root@web2 ~]# ps -ef |grep nginx
root      1878     1  0 02:17 ?        00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx     1879  1878  0 02:17 ?        00:00:00 nginx: worker process      
root      1883  1854  0 02:17 pts/0    00:00:00 grep nginxproxy: 192.168.4.5                   eth0


在代理服务器访问web1、web2

[root@service ~]# curl http://192.168.2.100
web1:192.168.2.100
[root@service ~]# curl http://192.168.2.200
web2:192.168.2.200

nginx代理:
代理服务器:192.168.4.5
后端服务器:192.168.2.100

一、location和proxy_pass都不带uri路径。

代理服务器的配置:192.168.4.5

server {
        listen       80;
        server_name  www.a.com;
        location / {
            proxy_pass http://192.168.2.100;
        }

后端服务器的配置:192.168.2.200

server {
        listen       80;
        server_name  localhost;
        location / {
            root   html;
            index  index.html index.htm;
        }[root@web2 ~]# vim /usr/local/nginx/html/index.html 
web2:192.168.2.200

客户端访问:192.168.4.1

[root@client ~]# curl http://192.168.4.5
web2:192.168.2.200

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

代理服务器的配置:192.168.4.5

server {
        listen       80;
        server_name  www.a.com;
        location /data/web/ {
            proxy_pass http://192.168.2.200;
            root   html;
            index  index.html index.htm;
        }

后端服务器的配置:192.168.2.200

server {
        listen       80;
        server_name  localhost;
        location /data {
            root   html;
            index  index.html index.htm;
        }
[root@web2 ~]# mkdir -p /usr/local/nginx/html/data/web
[root@web2 ~]# echo "/usr/local/nginx/html/data/web  test" > /usr/local/nginx/html/data/web/index.html
[root@web2 ~]# cat /usr/local/nginx/html/data/web/index.html
/usr/local/nginx/html/data/web  test

客户端访问:192.168.4.1

[root@client ~]# curl http://192.168.4.5/data/web/
/usr/local/nginx/html/data/web  test

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

代理服务器的配置:192.168.4.5

server {
        listen       80;
        server_name  www.a.com;
        location / {
            proxy_pass http://192.168.2.200/data/;
            root   html;
            index  index.html index.htm;
        }

后端服务器的配置:192.168.2.200

server {
        listen       80;
        server_name  localhost;
        location /  {
            root   html;
            index  index.html index.htm;
        }
[root@web2 ~]# mkdir -p /usr/local/nginx/html/data/
[root@web2 ~]# echo "/usr/local/nginx/html/data/   test" > /usr/local/nginx/html/data/index.html
[root@web2 ~]# cat /usr/local/nginx/html/data/index.html
/usr/local/nginx/html/data/  test

客户端访问:192.168.4.1

[root@client ~]# curl http://192.168.4.5/data/
/usr/local/nginx/html/data/  test

访问看起来很正常,稍作修改
加上location的uri,后端服务器加个子目录:

代理服务器的配置:192.168.4.5

server {
        listen       80;
        server_name  www.a.com;
        location /web/ {
            proxy_pass http://192.168.2.200/data/;
            root   html;
            index  index.html index.htm;
        }

后端服务器的配置:192.168.2.200

server {
        listen       80;
        server_name  localhost;
        location /  {
            root   html;
            index  index.html index.htm;
        }

客户端访问:192.168.4.1

[root@client ~]# curl http://192.168.4.5/web/
/usr/local/nginx/html/data/  test

验证结果还是proxy_pass指定的uri路径,与location没有关系了。

 

四、获取远程客户端真实ip地址:

代理服务器的配置:192.168.4.5

server {
        listen       80;
        server_name  www.a.com;
        location /web/ {
            proxy_pass http://192.168.2.200/data/;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            root   html;
            index  index.html index.htm;
        }

后端服务器的配置:192.168.2.200

log_format proxy  '$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 proxy;[root@web2 ~]# tailf /usr/local/nginx/logs/proxy.log 
"192.168.2.5" - - [22/Aug/2021:09:18:36 +0800] "GET /data/ HTTP/1.0" "200""34" "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.18 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2" "192.168.4.1"

客户端访问:192.168.4.1

[root@client ~]# curl http://192.168.4.5/web/
/usr/local/nginx/html/data/  test

五、缓存代理服务器配置:
代理服务器的配置:192.168.4.5

[root@service ~]# mkdir -p /data/nginx/cache
proxy_cache_path /data/nginx/cache max_size=10g levels=1:2 keys_zone=nginx_cache:10m  inactive=60m use_temp_path=off; server {
        listen       80;
        server_name  www.a.com;
        location /web/ {
            proxy_pass http://192.168.2.200/data/;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_cache nginx_cache;
            proxy_cache_key $host$uri$is_args$args;
            proxy_cache_valid 200 304 302 1d;
            root   html;
            index  index.html index.htm;
        }
[root@service ~]# /usr/local/nginx/sbin/nginx -s reload
[root@service ~]# ls /data/nginx/cache/
temp


客户端访问后再查看

[root@service ~]# ls /data/nginx/cache/


6 temp
删除缓存

[root@service ~]# rm -rf /data/nginx/cache/*

后端服务器的配置:192.168.2.200
删除资源

[root@web2 ~]# rm -f /usr/local/nginx/html/data/index.html

客户端访问:192.168.4.1

[root@client ~]# curl http://192.168.4.5/web/
/usr/local/nginx/html/data/  test


删除后端服务器的资源后再访问

[root@client ~]# curl http://192.168.4.5/web/
/usr/local/nginx/html/data/  test


删除代理服务器的缓存后再访问

[root@client ~]# curl http://192.168.4.5/web/
<html>
<head><title>403 Forbidden</title></head>
<body bgcolor="white">
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.8.0</center>
</body>
</html>

nginx 负载均衡的配置

nginx 负载分配方式
NGINX目前支持4种分配方式
--轮询(默认的):逐一循环调度
--weight:指定轮询几率,权重值和访问比率成正比
--ip_hash:根据客户端IP分配固定的后端服务器
--Fair:按后端服务器响应时间短的优先分配

服务器组主机状态
状态类型
--down:表示当前server暂时不参与负载。
--max_fails:允许请求失败的次数(默认为1)
--fail_timeout:max_fails次失败后,暂停提供服务的时间
--backup: 备份服务器

轮询

upstream webserver {
          server 192.168.2.100 ;
          server 192.168.2.200;
    }


权重(默认值为1 )

upstream servers {
          server 192.168.2.100 weight=2;
          server 192.168.2.200;
    }
ip_hash(相同的客户端访问相同的服务器)
   upstream servers {
          ip_hash;
          server 192.168.2.100;
          server 192.168.2.200;
    }

Fair(根据响应时间均衡)
# 下载模块:
wget https://github.com/gnosek/nginx-upstream-fair/archive/master.zip
# 解压:
unzip master.zip
# 修改源码bug:
sed -i 's/default_port/no_port/g' ngx_http_upstream_fair_module.c
# 预编译:
./configure --prefix=/usr/local/nginx --add-module=../echo-nginx-module --with-
http_stub_status_module --add-module=../nginx-upstream-fair-master
# 编译/安装:
make && make install
# 配置:

upstream servers {
         fair;
          server 192.168.2.100;
          server 192.168.2.200;
    }

最大错误连接次数

upstream servers {
          server 192.168.2.100 max_fails=1 fail_timeout=30;
          server 192.168.2.200 max_fails=1 fail_timeout=30;
    }

down:当前server暂时不参与负载。

upstream servers {
          server 192.168.2.100 max_fails=1 fail_timeout=30;
          server 192.168.2.200 down;
    }


backup: 备份服务器

upstream servers {
          server 192.168.2.100 max_fails=1 fail_timeout=30;
          server 192.168.2.200 backup;
    }server {
        listen       80;
        server_name  www.a.com;
        location / {
            proxy_pass http://servers;
            root   html;
            index  index.html index.htm;
        }