Nginx负载均衡配置简易实现

来源:互联网 发布:java帮助文档手机版 编辑:程序博客网 时间:2024/06/05 23:08
什么是动静分离? 其实就是七层调度,把动态文件的请求和静态文件的请求分别调到不同的后台服务器什么是网站数据切分?其实也是七层调度比如我要把新浪新闻,新浪体育给分开方法1:用dnswww.baidu.comnews.baidu.comtieba.baidu.com这几个域名得到的ip不同,所以其实是不同的站点方法2:前端使用代理通过代理软件七层调度来分离以location来分sports.sina.com.cn/nba/sports.sina.com.cn/cba/以文件名后缀来分sports.sina.com.cn/xxx/xxxx/xxx/xxx.pngsports.sina.com.cn/xxx/xxxx/xxx/xxx.php================================================================================================1,四台机器,192.168.100.0/24为kvm的virbr1网络(模拟外网),172.16.25.0/24为桥接网络(模拟内网)2,web1我这里用的是本来搭建好的lnmp(参考历史文章),为了后面方便测试(但这里直接把lnmp的web家目录改成discuz的家目录/usr/share/nginx/html/discuz)3,web2这里简单的安装并启动rpm版的apache,并做一个简单主页就好4,nginx这台需要按下面的第一步过程进行安装,这次只安装nginx就好,不用安装php,mysql等(因为是主要做代理)5,客户端最好有图形界面,并安装firefox浏览器nginx 反向代理 client(宿主机)  192.168.100.1192.168.100.4eth0   defaultnginx(虚拟机1)172.16.25.4eth1   桥接       web1(虚拟机2)web2(虚拟机3)   172.16.25.2172.16.25.3 (lnmp)安装nginx# yum install nginx======================================================================================例一:使用前端nginx代理后面一台web client(宿主机)  192.168.100.1      |      |      |192.168.100.4nginx(虚拟机1)172.16.25.4      |      |      |        web1(虚拟机2)    172.16.25.2   # cat /etc/nginx/nginx.conf |grep -v '#'user nginx;worker_processes auto;error_log /var/log/nginx/error.log;pid /run/nginx.pid;include /usr/share/nginx/modules/*.conf;events {    worker_connections 1024;}http {    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '                      '$status $body_bytes_sent "$http_referer" '                      '"$http_user_agent" "$http_x_forwarded_for"';    access_log  /var/log/nginx/access.log  main;    sendfile            on;    tcp_nopush          on;    tcp_nodelay         on;    keepalive_timeout   65;    types_hash_max_size 2048;    include             /etc/nginx/mime.types;    default_type        application/octet-stream;    include /etc/nginx/conf.d/*.conf;    server {        listen       80 default_server;        listen       [::]:80 default_server;        server_name  192.168.100.4;--改成模拟nginx的外网ip        root         /usr/share/nginx/html;index     index.php index.html;        include /etc/nginx/default.d/*.conf;        location / {proxy_pass http://172.16.25.2/;proxy_set_header Host $host;proxy_set_header X-Forwarded-For $remote_addr;        }       --这个例子主要讨论这一段,五行        error_page 404 /404.html;            location = /40x.html {        }        error_page 500 502 503 504 /50x.html;            location = /50x.html {        }    }}--说明:下面这两句是做外网转内网双网段架构必需要加的proxy_set_header Host $host;proxy_set_header X-Forwarded-For $remote_addr;客户端使用firefox验证访问 http://192.168.100.4/--得到后台web上安装的lnmp验证:把后面的web关闭,客户端也访问不了,说明nginx默认没有缓存功能例二:locate网站数据切分 client(宿主机)  192.168.100.1192.168.100.4nginx(虚拟机1)172.16.25.4       web1(虚拟机2)web2(虚拟机3)   172.16.25.2172.16.25.3把例一nginx配置文件里的那五行改成下面两段(加在server { }配置段中 ):        location /nba/ {proxy_pass http://172.16.25.2/;proxy_set_header Host $host;proxy_set_header X-Forwarded-For $remote_addr;        }        location /cba/ {proxy_pass http://172.16.25.3/;proxy_set_header Host $host;proxy_set_header X-Forwarded-For $remote_addr;        }# systemctl restart nginx客户端验证http://192.168.100.4/nba/http://192.168.100.4/cba/例三:网站动静分离 client(宿主机)  192.168.100.1192.168.100.4nginx(虚拟机1)172.16.25.4       web1(虚拟机2)web2(虚拟机3)   172.16.25.2172.16.25.3把例二的配置再改成如下(加在server { }配置段中 ):        location ~ \.(html|htm|gif|jpeg|jpg|css|js|png|swf)$ {proxy_pass http://172.16.25.2;proxy_set_header Host $host;proxy_set_header X-Forwarded-For $remote_addr;        }        location ~ \.(php|cgi)$ {proxy_pass http://172.16.25.3;proxy_set_header Host $host;proxy_set_header X-Forwarded-For $remote_addr;        }# systemctl restart nginx客户端测试(过程省略)例四:代理后端时使用负载均衡(load balance) client(宿主机)  192.168.100.1192.168.100.4nginx(虚拟机1)172.16.25.4       web1(虚拟机2)web2(虚拟机3)   172.16.25.2172.16.25.3下面一段加到http 和 server 之间upstream backendweb {server 172.16.25.2 weight=1 max_fails=2 fail_timeout=1s;server 172.16.25.3 weight=1 max_fails=2 fail_timeout=1s;        }--weight代表权重,max_fails=2 fail_timeout=1s代表健康检查(检查后台web是否ok,访问超时1秒,并两次超时,则认为不健康)把例三的配置再改成如下(加在server { }配置段中 ):        location ~ \.(txt|html)$ {proxy_pass http://backendweb;--backendweb是一个名称,对应上面upstream的配置proxy_set_header Host $host;proxy_set_header X-Forwarded-For $remote_addr;}# systemctl restart nginx客户端验证访问http://192.168.100.4/1.txt--验证时,会发现客户端针对同一个URL的访问也会一次web1一次web2,这再次验证说明了nginx默认并没有squid或varnish那样的缓存功能负载均衡(lb  load banlance)一般要注意四个方面:1,算法  round-robin2,健康检查 3,会话保持  4,数据一致rsync   drbd    共享存储  分布式存储   client requestLB(loaded balanced)web1web2例五:使用ip_hash,实现同一IP客户端一旦调到一台,就一直调那一台 client(宿主机)  192.168.100.1192.168.100.4nginx(虚拟机1)172.16.25.4       web1(虚拟机2)web2(虚拟机3)   172.16.25.2172.16.25.3upstream backendweb {ip_hash;--在上个例子的基础上只加这一句;server 172.16.25.2 weight=1 max_fails=2 fail_timeout=1s;server 172.16.25.3 weight=1 max_fails=2 fail_timeout=1s;        }# systemctl restart nginx客户端验证访问http://192.168.100.4/1.txt--nginx的ip_hash的意思是,如果一个客户端的访问被调度到其中一台后台服务器,那么同一个IP来的访问都只会被调到这个后台服务器;这里测试时,如果都用同一个网段的内网IP来做客户端测试,可能会都只转到一个后台(因为nginx的hash算法是按网段来算的,如果是公网不同网段的客户端IP就不一样了)对于nginx的upstrem算法总结:1,round-robin轮循(平均分配)2,weight权重(人为地分配权重,用于后台服务器性能不均的情况)3,fair响应时间(按后台的响应时间来分配,需要第三模块,但如果后台服务器都在内网,就没太大必要使用这种算法了)4,url_hash按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为多台缓存时比较有效,提高缓存命中率5,ip_hash在负载均衡的基础上加上会话保持(优点是配置方便,缺点是不能完全的负载均衡)=======================================================================client  192.168.100.1  |  |     192.168.100.4(模拟网站公网ip,整个架构的域名假设为web.cluster.com )      nginx 反向代理     |     172.16.25.4  |   -----------  |    | 命中  hit 直接返回动态程序文件.php  |    |   |               squid(web加速,缓存静态文件或图片) 直接找web  |    |   ----    |    没命中 miss 找后端web去取 |    | 172.16.25.3lnmp  <---- |            172.16.25.2实验前准备:1,所有机器配置主机名并在/etc/hosts里互相绑定主机2,关闭firewalld,selinux3,关闭NetworkManager,并配置静态ip4,配置本地yum,epel源,163源5,时间同步第一大步:在上图中的lnmp上安装并配置后面的网站第二大步:在上图中的nginx服务器上安装并配置nginx1,安装nginx# yum install nginx  2,配置文件如下# cat /etc/nginx/nginx.conf |grep -v '#'user nginx;worker_processes auto;error_log /var/log/nginx/error.log;pid /run/nginx.pid;include /usr/share/nginx/modules/*.conf;events {    worker_connections 1024;}http {    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '                      '$status $body_bytes_sent "$http_referer" '                      '"$http_user_agent" "$http_x_forwarded_for"';    access_log  /var/log/nginx/access.log  main;    sendfile            on;    tcp_nopush          on;    tcp_nodelay         on;    keepalive_timeout   65;    types_hash_max_size 2048;    include             /etc/nginx/mime.types;    default_type        application/octet-stream;    include /etc/nginx/conf.d/*.conf;upstream squid {    server 172.16.25.3 weight=1 max_fails=2 fail_timeout=3s;}upstream web {    server 172.16.25.2 weight=1 max_fails=2 fail_timeout=3s;}    server {        listen       80 default_server;        listen       [::]:80 default_server;        server_name  192.168.100.4;        root         /usr/share/nginx/html;        include /etc/nginx/default.d/*.conf;       location ~ .*\.php$ {            proxy_pass   http://web;            proxy_set_header Host $host;            proxy_set_header X-Forwarded-For $remote_addr;        }        location ~ .*\.(html|htm|gif|jpeg|jpg|css|js|png|swf)$ {            proxy_pass   http://squid;            proxy_set_header Host $host;            proxy_set_header X-Forwarded-For $remote_addr;        }        location / {            proxy_pass   http://web;            proxy_set_header Host $host;            proxy_set_header X-Forwarded-For $remote_addr;        }        error_page 404 /404.html;            location = /40x.html {        }        error_page 500 502 503 504 /50x.html;            location = /50x.html {        }    }}# systemctl restart nginx第三大步:在上图中的squid服务器上安装并配置squid1,安装squid# yum install squid -y2,配置squid主配置文件# vim /etc/squid/squid.confhttp_access allow all--把这一行前面的全删除,再把这行修改成允许所有http_port 80 accel vhost vport  --修改成支持反向代理模式,端口也为80与nginx的配置对应cache_dir ufs /var/spool/squid 256 16 256--打开缓存目录的定义这一句cache_peer 172.16.25.2 parent 80 0 no-query originserver name=webcache_peer_domain web web.cluster.com--web.cluster.com就是我现在模拟的整个网站架构的域名cache_peer_domain web 192.168.100.4--加上这三句,表示代理后台的lnmp的80端口;web.cluster.com为网站的域名,192.168.100.4为我这个架构最前端的nginx的IP3,启动squid# systemctl restart squid第四大步:验证在客户端机器192.168.100.129上首先绑定静态DNS --用于模拟DNS,如果不绑定,也可以直接使用公网IP192.168.100.4来访问,因为在squid里配置了(cache_peer_domain web web.cluster.com和 cache_peer_domain web 192.168.100.4 两句)cat /etc/hosts192.168.100.4  web.cluster.com    --IP要为前端nginx的IP,名字为这个网站的域名要和squid里的cache_peer_domain web web.cluster.com要对应1,在客户端用firefox访问http://web.cluster.com/或http://192.168.100.4/是可以正常看到我的lnmp安装的discuz论坛2,在客户端使用下面的命令验证discuz论坛的一个logo,可以看到在squid上命中的信息# curl -I http://web.cluster.com/static/image/common/logo.pngHTTP/1.1 200 OKServer: nginx/1.8.0Date: Mon, 23 Nov 2015 08:10:09 GMTContent-Type: image/pngContent-Length: 4425Connection: keep-aliveLast-Modified: Tue, 09 Jun 2015 02:21:12 GMTETag: "55764d98-1149"Accept-Ranges: bytesAge: 3227X-Cache: HIT from squid.cluster.comX-Cache-Lookup: HIT from squid.cluster.com:3128Via: 1.0 squid.cluster.com (squid/3.1.10)3,关闭squid,在客户端用firefox访问,会发现整个网站都没有图片(静态的元素)用curl -I  http://web.cluster.com/static/image/common/logo.png来验证也会报错因为我的架构里只有一台squid,再次启动squid后,一切又恢复正常4,关于squid手动清缓存# vim /etc/squid/squid.confacl purge_admin src 127.0.0.1acl purge method PURGEhttp_access allow purge_admin purgehttp_access deny all purge# systemctl restart squid最基本的清除一条缓存的操作,必须要在squid本机执行# squidclient -m PURGE -h 127.0.0.1 -p 80 http://192.168.100.4/static/image/common/logo.png-- -h参数后只能接127.0.0.1;-p 80是squid的监听端口;最后的路径就是客户端访问的路径如果要批量清除squid,可以使用下面的脚本(你需要修改成自己对应的路径)# vim /tmp/purge_squid.sh#!/bin/bashsquidcache_path="/var/spool/squid/"squidclient_path="/usr/bin/squidclient"grep -a -r $1 $squidcache_path/* | strings | grep "http" | while read urldo$squidclient_path -h 127.0.0.1 -m PURGE -p 80 $url > /dev/null 2>&1echo "$url被清除"done--注意:脚本的squidcache_path修改成你对应的缓存目录,squidclient_path修改成squidclient命令的路径;-h 127.0.0.1是因为我做了acl限制的,所以只能在squid本机上清除批量清除的方法:sh /tmp/purge_squid.sh .txt  --表示清除所有的.txt结尾的缓存sh /tmp/purge_squid.sh .     --表示清除所有缓存sh /tmp/purge_squid.sh /aaa/  --表示url里有/aaa/路径就清掉缓存===============================================================================在上面的架构基础上多加一台squid2(我这里IP为172.16.25.5)client 192.168.100.1  |  |192.168.100.4 nginx  |172.16.25.4  |    |------------|    |     |    |   squid1  squid2    |   172.16.25.3172.16.25.5     |------------|  |  | lnmp       172.16.25.2做法,在nginx配置要修改的为下面一段upstream squid {    server 172.16.25.3 weight=1 max_fails=2 fail_timeout=3s;    server 172.16.25.5 weight=1 max_fails=2 fail_timeout=3s;}# systemctl restart nginx在客户端用curl -I去测试多个不同的文件请求,看缓存情况,如:curl -I http://web.cluster.com/static/image/common/logo.pngcurl -I http://web.cluster.com/static/image/feed/task_b.pngcurl -I http://web.cluster.com/static/image/feed/album_b.pngcurl -I http://web.cluster.com/static/image/feed/portal_b.pngcurl -I http://web.cluster.com/static/image/feed/wall_b.png测试结果为:第一次squid1,第二次squid2,第三次squid1...以此类推(round-robin)但这个做法的缺点为:比如同一个url的请求,连续访问,它也会RR轮循给squid1和squid2,这样会造成两个squid重复缓存。改进的做法为:使用nginx的url_hash的算法,把同一个url的请求只给同一个后台squid,以提高缓存命中率。如果要做这个改进的话,只需要把nginx的配置再修改成如下:upstream squid {    hash $request_uri;    server 172.16.25.3 weight=1 max_fails=2 fail_timeout=3s;    server 172.16.25.5 weight=1 max_fails=2 fail_timeout=3s;}# systemctl restart nginx再次测试:结果为:新的请求仍然会RR轮循调给squid1和squid2,但已经请求过的地址再次被请求,会调给第一次调的squid,提高缓存命中率。=================================================================================
原创粉丝点击