一篇含金量hin高的Nginx反向代理与负载均衡指南

惨绿少年 2017-12-25 12:01:50

文章经作者授权转载,来源:惨绿少年的博客(http://www.cnblogs.com/clsn/p/8051514.html)

 

本文大纲:

  1. 集群是什么

  2. 为什么需要集群

  3. Nginx反向代理实践

  4. Nginx中常用模块说明

  5. 定义多个虚拟主机标签信息

  6. 根据URL目录地址转发的应用场景:基于目录(uri)进行转发

  7. 根据客户端的设备实现转发(user_agent)

  8. 利用扩展名进行转发

 

一、集群是什么

 

简单的说,集群就是指一组(若干个)相互独立的计算机,利用高速通信网络组成的一个较大的计算机服务系统,每个集群节点(即集群中的每台计算机)都是运行各自服务的独立服器。这些服务器之间可以彼此通信,协同向用户提供应用程序、系统资源和数据,并以单一系统的模式加以管理。当用户客户机请求集群系统时,集群给用户的感觉就是一个单一独立的服务器,而实际上用户请求的是一组集群服务器。

 

打开谷歌、百度的页面,看起来好简单,也许你觉得用几分钟就可以制作出相似的网页,而实际上,这个页面的背后是由成千上万台服务器集群协同工作的结果。而这么多的服务器维护和管理,以及相互协调工作也许就是你未来的工作职责了。

 

若要用一句话描述集群,即一堆服务器合作做同一件事,这些机器可能需要整个技术团队架构、设计和统一协调管理,这些机器可以分布在一个机房,也可以分布在全国全球各个地区的多个机房。

 

二、为什么要有集群
 

 

 

高性能、价格有效性、可伸缩性、高可用性

透明性、可管理性、可编辑性

 

1、集群种类

 

  • 负载均衡集群:LB 解决调度问题

  • 高可用集群:HA 解决单点故障问题(keeplived)

  • 高性能计算集群:HP

  • 网络计算集群:GC

 

2、硬件设备

 

F5 设备   A10

 

3、软件

 

  • Nginx (7层,1.9版本之后支持4层)

  • LVS (4层)

  • HAproxy (4层,7层)

 

4、负载均衡概念说明

 

  • 对用户的访问请求进行调度管理

  • 对用户的访问请求进行压力分担

 

 

5、反向代理

 

接收用户请求代替用户向后端访问

反向代理与数据转发的区别

 

6、压力测试的方式

 

ab (Apache里的命令) 

通过  yum install httpd-tools 获得

 

三、Nginx反向代理实践
 

 

1、地址规划说明

 

 

  • ip命令说明

 

ip address show  查看ip地址

ip route show  查看路由信息

 

2、反向代理与数据转发的区别

 

 

3、安装部署Nginx过程(安装命令集)

 

yum install -y pcre-devel openssl-devel

mkdir -p /server/tools

cd /server/tools

wget -q http://nginx.org/download/nginx-1.10.3.tar.gz

ls -l nginx-1.10.3.tar.gz

useradd www -s /sbin/nologin -M

tar xf nginx-1.10.3.tar.gz

cd nginx-1.10.3

./configure  --user=nginx --group=nginx --prefix=/application/nginx-1.10.3 --with-http_stub_status_module  --with-http_ssl_module

make

make install

ln -s /application/nginx-1.10.3 /application/ngin

 

4、编写Nginx配置文件(统一Web服务器配置)

 

worker_processes  1;

events {

    worker_connections  1024;

}

http {

    include       mime.types;

    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '

                      '$status $body_bytes_sent "$http_referer" '

                      '"$http_user_agent" "$http_x_forwarded_for"';

    server {

        listen       80;

        server_name  bbs.etiantian.org;

        location / {

            root   html/bbs;

            index  index.html index.htm;

        }

      access_log  logs/access_bbs.log  main;

    }       

    server {

        listen       80;

        server_name  www.etiantian.org;

        location / {

            root   html/www;

            index  index.html index.htm;

        }

        access_log  logs/access_www.log  main;

    }

}

 

5、统一Nginx测试环境 (Web文件)

 

mkdir -p /application/nginx/html/{www,bbs}

for name in www bbs; do echo $name `hostname` >/application/nginx/html/$name/xiaoxinxin.html;done

for name in www bbs; do cat /application/nginx/html/$name/xiaoxinxin.html;done

 

6、测试

 

[root@lb01 ~]# curl -H host:bbs.etiantian.org  10.0.0.8/xiaoxinxin.html

bbs web01

[root@lb01 ~]# curl -H host:bbs.etiantian.org  10.0.0.7/xiaoxinxin.html

bbs web02

[root@lb01 ~]# curl -H host:bbs.etiantian.org  10.0.0.9/xiaoxinxin.html

bbs web03

[root@lb01 ~]# curl -H host:www.etiantian.org  10.0.0.8/xiaoxinxin.html

www web01

[root@lb01 ~]# curl -H host:www.etiantian.org  10.0.0.7/xiaoxinxin.html

www web02

[root@lb01 ~]# curl -H host:www.etiantian.org  10.0.0.9/xiaoxinxin.html

www web03

 

7、配置负载服务文件

 

worker_processes  1;

events {

    worker_connections  1024;

}

http {

    include       mime.types;

    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;                                 

    upstream server_pools {

        server 10.0.0.7:80;

        server 10.0.0.8:80;

        server 10.0.0.9:80;

    }

    server {

        listen 80;

        server_name bbs.etiantian.org;

        location / {

            proxy_pass http://server_pools;

        }

    }

 

8、测试访问

 

[root@lb01 conf]# curl -H host:bbs.etiantian.org 10.0.0.5/xiaoxinxin.html

bbs web03

[root@lb01 conf]# curl -H host:bbs.etiantian.org 10.0.0.5/xiaoxinxin.html

bbs web02

[root@lb01 conf]# curl -H host:bbs.etiantian.org 10.0.0.5/xiaoxinxin.html

bbs web01

 

四、Nginx中常用模块说明
 

 

 

ngx_http_status_module

ngx_http_ssl_module

ngx_http_log_module

ngx_http_upstream_module

ngx_http_proxy_module

 

1、模块调度算法

 

  • 定义轮询调度算法-rr-默认调度算法

  • 定义权重调度算法-wrr

  • 定义静态调度算法-ip_hash

  • 定义最小的连接数-least_conn

 

2、Nginx反向代理相关两个模块

 

  • upstream 模块:类似与一个池塘,将Nginx节点放置到池塘中

  • proxy模块:用池塘里面的Nginx节点,利用proxy进行调用

 

3、upstream模块核心参数简介

 

  • weight 权重

  • max_fails 抛得次数

  • fail_timeout 失败的超时时间

  • backup  备份

 

4、weight 参数实践 (权重)

 

upstream 模块只能在http区块里

 

worker_processes  1;

events {

    worker_connections  1024;

}

http {

    include       mime.types;

    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    upstream server_pools{

         server 10.0.0.7:80 weight=1;

         server 10.0.0.8:80 weight=2;

    }

    server{

       listen 80;

       server_name bbs.etiantian.org;

       location / {

          proxy_pass http://server_pools;

       }

    }

}

 

测试

 

[root@test tools]# curl 10.0.0.5

web01 www

[root@test tools]# curl 10.0.0.5

web01 www

[root@test tools]# curl 10.0.0.5

web02 www

[root@test tools]# curl 10.0.0.5

web01 www

[root@test tools]# curl 10.0.0.5

web01 www

[root@test tools]# curl 10.0.0.5

web02 www

 

5、其它参数说明

 

  • max_fails:失败的尝试次数

  • fail_timeout:失败后的再次尝试时间

  • backup 备份节点:所有的节点都挂掉后数据才会请求web01

 

server 10.0.0.7:80 weight=1 max_fails=3 fail_timeout=10 ;

server 10.0.0.8:80 weight=2 max_fails=3 fail_timeout=10 backup;

 

测试,将web02停掉

[root@test tools]# curl 10.0.0.5

web02 www

[root@test tools]# curl 10.0.0.5

web02 www

 

停掉web02后

[root@test tools]# curl 10.0.0.5

web01 www

[root@test tools]# curl 10.0.0.5

web01 www

[root@test tools]# curl 10.0.0.5

 

6、访问抓包

 

用户请求报文

 

 

负载均衡请求报文

 

 

说明:hosts 主机头不同,未配置proxy_set_header Host $host 参数,在负载均衡访问的时候会不带hosts信息。

 

7、upsrteam参数详细说明

 

 

 

weight :调节服务器的请求分配权重。1.4.8 上述命令的说明如下:

  • check :开启对该服务器健康检查。

  • inter:设置连续两次的健康检查间隔时间,单位毫秒,默认值2000。

  • rise :指定多少次连续成功的健康检查后,即可认定该服务器处于可用状态。

  • fall :指定多少次不成功的健康检查后,即认为服务器为宕机状态,默认值3。

  • maxconn :指定可被发送到该服务器的最大并发连接数。

 

虽然Nginx本身不支持一致性hash算法,但Nginx的分支Tengine支持。详细可见: 

http://tengine.taobao.org/document_cn/http_upstream_consistent_hash_cn.html

 

9、ip_hash 参数实践

 

每个访问的用户都会生成一个hash值。

 

每个请求按客户端 IP的 hash结果分配,当新的请求到达时,先将其客户端 IP通过哈希算法哈希出一个值,在随后的客户端请求中,客户IP的咍希值只要相同,就会被分配至同一台服务器,该调度算法可以解决动态网页的session共享问题,但有时会导致请求分配不均,即无法保证1:1的负载均衡,因为在国内大多数公司都是NAT上网横式,多个客户端会对应_个外部IP ,所以,这些客户端都会被分配到同一节点服务器,从而导致请求分配不均。

 

LVS负载均衡的-p参数、Keepalived配置里的 persistence jimeout 50参数都类似这个 Nginx里的ip_hash参数,其功能都可以解决动态网页的session共享问题。

 

worker_processes  1;

events {

    worker_connections  1024;

}

http {

    include       mime.types;

    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    upstream server_pools{

            ip_hash;

         server 10.0.0.7:80;

         server 10.0.0.8:80;

    }

    server{

       listen 80;

       server_name bbs.etiantian.org;

       location / {

          proxy_pass http://server_pools;

       }

    }

}

 

10、least_conn 参数

 

 

看谁闲,谁闲发送给谁

 

least_conn算法会根据后端节点的连接数来决定分配情况,哪个机器连接数少就分发。

 

11、fair 参数

 

 

看谁响应的快

 

此算法会根据后端节点服务器的响应时间来分配请求,响应时间短的优先分配。这是更加智能的调度算法。此种算法可以依据页面大小和加载时间长短智能地进行负载均衝,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配。Nginx本身不支持fair调度算法,如果需要使用这种调度算法,必须下载Nginx的相关模块upstream_fair。

 

示例如下:

upstream name {

server 192.168.1.1;

server 192.168.1.2;

fair;

}

 

除了上面这些算法外,还有一些第三方调度算法,例如:url_hash、一致性hash算法等。

 

12、调度算法

 

  • 定义轮询调度算法 rr 默认调度算法 平均分配

  • 定义权重调度算法 wrr

  • 定义静态调度算法 ip-hash

  • 定义最小的连接数-least_conn

 

13、Nginx负载均衡相关重要参数

 

 

14、反向代理排错思路

 

  • 先在lb01上访问后端节点进行测试

  • 在lb01上访问本地地址进行测试

  • 在浏览器上进行测试

  • 缓存、域名解析

 

15、proxy_next_uptream 参数

 

当Nginx接收后端服务器返回proxy_next_upstream 参数定义的状态码时,会将这个请求转发给正常工作的后端服务器,例如500、502、503、504,此参数可以提升用户的访问体验。

 

五、定义多个虚拟主机标签信息
 

 

1、proxy_set_header 参数


配置文件

 

[root@lb01 conf]# cat nginx.conf

worker_processes  1;

events {

    worker_connections  1024;

}

http {

    include       mime.types;

    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    upstream server_pools{

         server 10.0.0.7:80;

         server 10.0.0.8:80;

    }

    server{

       listen 80;

       server_name bbs.etiantian.org;

       location / {

          proxy_pass http://server_pools;

              proxy_set_header Host $host;

       }

    }

    server{

       listen 80;

       server_name www.etiantian.org;

       location / {

          proxy_pass http://server_pools;

               proxy_set_header Host $host;

       }

    }

 

}


问抓包

 

该参数在负载服务器在访问后端服务器的时候 会带上hosts信息。

 

 

2、X-Forwarded-For 参数

 

proxy_set_header X-Forwarded-For $remote_addr;

代理的啥时候在后面显示真实的IP地址

 

[root@lb01 conf]# cat nginx.conf

worker_processes  1;

events {

    worker_connections  1024;

}

http {

    include       mime.types;

    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    upstream server_pools{

         server 10.0.0.8:80;

         server 10.0.0.7:80;

         server 10.0.0.9:80;

    }

    server{

       listen 80;

       server_name bbs.etiantian.org;

       location / {

          proxy_pass http://server_pools;

             proxy_set_header Host $host;

          proxy_set_header X-Forwarded-For $remote_addr;

       }

    }

    server{

       listen 80;

       server_name www.etiantian.org;

       location / {

          proxy_pass http://server_pools;

             proxy_set_header Host $host;

             proxy_set_header X-Forwarded-For $remote_addr;

       }

    }

    server{

       listen 80;

       server_name blog.etiantian.org;

       location / {

          proxy_pass http://server_pools;

             proxy_set_header Host $host;

             proxy_set_header X-Forwarded-For $remote_addr;

       }

    }

 

}

 

参看日志信息

 

1 10.0.0.5 - - [30/Oct/2017:12:36:10 +0800] "GET / HTTP/1.0" 200 10 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36" "10.0.0.1"

2 10.0.0.5 - - [30/Oct/2017:12:36:10 +0800] "GET /favicon.ico HTTP/1.0" 404 571 "http://www.etiantian.org/" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36" "10.0.0.1"

 

该参数配置,会在访问日志的后面加上真正的访问用户IP。

 

3、http proxy 模块相关参数说明

 

 

六、相据URL目录地址转发的应用场景
 

 

 
于目录(uri)进行转发--网站动静分离
 

 

根据HTTP的URL进行转发的应用情况,被称为第7层(应用层)的负载均衡,而LVS的负载均衡一般用于TCP等的转发,因此被称为第4层(传输层)的负载均衡。

 

在企业中,有时希望只用一个域名对外提供服务,不希望使用多个域名对应同一个产品业务,此时就需要在代理服务器上通过配置规则,使得匹配不同规则的请求会交给不同的服务器池处理。这类业务有:

 

  • 业务的域名没有拆分或者不希望拆分,但希望实现动静分离、多业务分离,

  • 不同的客户端设备(例如:手机和 PC端)使用同一个域名访问同一个业务网站,就需要根 据规则将不同设备的用户请求交给后端不同的服务器处理,以便得到最佳用户体验。

  

 

第一个里程碑: 服务器规划

 

 

第二个里程碑:创建/设置upstream负载信息

 

upstream upload_pools {

  server 10.0.0.8:80;

}

upstream static_pools {

  server 10.0.0.7:80;

}

upstream default_pools {

  server 10.0.0.9:80;

}

 

第三个里程碑:如何调用upstream信息

 

location /static/ {

    proxy_pass http://static_pools;

    proxy_set_header Host $host;

    proxy_set_header X-Forwarded-For $remote_addr;

}

 location /upload/ {

    proxy_pass http://upload_pools;

    proxy_set_header Host $host;

    proxy_set_header X-Forwarded-For $remote_addr;

}

 location / {

    proxy_pass http://default_pools;

    proxy_set_header Host $host;

    proxy_set_header X-Forwarded-For $remote_addr;

}

 

第四个里程碑: 编写配置文件lb01

 

worker_processes  1;

events {

    worker_connections  1024;

}

http {

    include       mime.types;

    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '

                      '$status $body_bytes_sent "$http_referer" '

                      '"$http_user_agent" "$http_x_forwarded_for"';                     

    upstream upload_pools {

      server 10.0.0.8:80;

    }

 

    upstream static_pools {

      server 10.0.0.7:80;

    }

 

    upstream default_pools {

      server 10.0.0.9:80;

    }

 

    server {

        listen 80;

        server_name www.etiantian.org;

    location /static/ {

        proxy_pass http://static_pools;

        proxy_set_header Host $host;

        proxy_set_header X-Forwarded-For $remote_addr;

    }

 

        location /upload/ {

            proxy_pass http://upload_pools;

        proxy_set_header Host $host;

        proxy_set_header X-Forwarded-For $remote_addr;

    }

 

     location / {

            proxy_pass http://default_pools;

        proxy_set_header Host $host;

        proxy_set_header X-Forwarded-For $remote_addr;

    }

         access_log  logs/access_www.log  main;

    }

}

 

6、第五个里程碑: 创建环境

 

www.etiantian.org/xxx.html

www.etiantian.org/upload/xxx.html

www.etiantian.org/static/xxx.html

 

##web01

mkdir -p /application/nginx/html/www/upload

echo  "web01 upload" >/application/nginx/html/www/upload/xxx.html

 

##web02

mkdir -p /application/nginx/html/www/static

echo  "web02 static" >/application/nginx/html/www/static/xxx.html

 

##web03

echo  "web03 default" >/application/nginx/html/www/xxx.html

 

第六个里程碑: 进行测试

 

[root@lb01 conf]# curl -H  host:www.etiantian.org  10.0.0.5/upload/

web01 upload:/application/nginx/html/www/upload

[root@lb01 conf]# curl -H  host:www.etiantian.org  10.0.0.5/static/

web02,/application/nginx/html/www/static

[root@lb01 conf]# curl -H  host:www.etiantian.org  10.0.0.5/

web03 www

 

浏览器进行访问测试

 

 

七、根据客户端的设备实现转发(user_agent)
 

 

1、 user_agent的应用

 

 

2、修改lb01配置文件

 
iew Code lb01配置文件

 

worker_processes  1;

events {

     worker_connections  1024;

}

http {

     include       mime.types;

     default_type  application/octet-stream;

     sendfile        on;

     keepalive_timeout  65;

     log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '

                       '$status $body_bytes_sent "$http_referer" '

                       '"$http_user_agent" "$http_x_forwarded_for"';

     upstream upload_pools {

       server 10.0.0.8:80;

     }

     upstream static_pools {

       server 10.0.0.7:80;

     }

    upstream default_pools {

       server 10.0.0.9:80;

     }

     server {

         listen 80;

         server_name www.etiantian.org;

         location / {

          if ($http_user_agent ~* "MSIE")

           {

             proxy_pass http://static_pools;

           }

          if ($http_user_agent ~* "Chrome")

           {

             proxy_pass http://upload_pools;

           }

         proxy_pass http://default_pools;

            proxy_set_header Host $host;

                }

          access_log  logs/access_www.log  main;

     }

}

 

3、进行测试

 

基于上一步的操作,现在可以之间的进行访问测试

curl -A 指定访问类型

 

[root@lb01 conf]# curl -A MSIE -H host:www.etiantian.org 10.0.0.5

web02 www

[root@lb01 conf]# curl -A Chrome -H host:www.etiantian.org 10.0.0.5

web01 www

[root@lb01 conf]# curl -A xx -H host:www.etiantian.org 10.0.0.5

web03 www

 

八、利用扩展名进行转发
 

 

利用后缀名进行转发与Nginx中的基于后缀的转跳一样实现。

 

location ~.*.(gif|ipg|jpeg|png|bmp|swf|css|js)$ {

        peoxy_pass http://static_pools;

           include proxy.conf

}

 

最新评论
访客 2018年05月22日

立场大于分析

访客 2018年05月15日

不先从业务上优化,发现并消灭慢查询;一来就改架构,…

访客 2018年05月12日

我感觉标题不应该叫上云引发的雪崩

访客 2018年05月10日

docker run -d --name=sqlops504 --net=host p…

访客 2018年05月09日

支持,加油

活动预告