负载均衡介绍及Nginx简单实现
负载均衡
1. 介绍
严格的来说,Nginx仅仅是作为Nginx Proxy反向代理使用的,因为这个反向代理功能表现的是负载均衡的效果,所以本文称为负载均衡。
反向代理与负载均衡的区别:
- 负载均衡是转发用户请求的数据包
- 反向代理是接收用户的请求然后重新发起请求去请求后面的节点
注:负载均衡是转发请求,在RS服务器中可以直接看到用户的真实IP
反向代理是代替用户去发起请求,在RS服务器中默认看到的是代理的IP,可以在配置文件中修改。
举例:找人办事
- 负载均衡相当于别人找你办事,你告诉他谁可以帮助他完成事情,让他自己去找,结果直接返回给他。
- 反向代理相当于别人找你办事,你把事情接下帮助他完成事情,然后把结果告诉他。
四层负载工作原理
通过报文中的目标地址和端口
,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。
负载均衡设备在接收到第一个来自客户端的SYN 请求时,即通过上述方式选择一个最佳的服务器,并对报文中目标IP地址进行修改(改为后端服务器IP),直接转发给该服务器。TCP的连接建立,即三次握手是客户端和服务器直接建立的,负载均衡设备只是起到一个类似路由器的转发动作。在某些部署情况下,为保证服务器回包可以正确返回给负载均衡设备,在转发报文的同时可能还会对报文原来的源地址进行修改。
七层负载工作原理
也称为“内容交换”,通过报文中的真正有意义的应用层内容
,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。
负载均衡设备如果要根据真正的应用层内容再选择服务器,只能先代理最终的服务器和客户端建立连接(三次握手)后,才可能接受到客户端发送的真正应用层内容的报文,然后再根据该报文中的特定字段,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。负载均衡设备在这种情况下,更类似于一个代理服务器。负载均衡和前端的客户端以及后端的服务器会分别建立TCP连接。所以从这个技术原理上来看,七层负载均衡明显的对负载均衡设备的要求更高,处理七层的能力也必然会低于四层模式的部署方式。
2. 常用的开源软件
2.1 LVS
使用集群技术和Linux操作系统实现一个高性能、高可用的服务器,它具有很好的可伸缩性(Scalability)、可靠性(Reliability)和可管理性(Manageability),感谢章文嵩博士为我们提供如此强大实用的开源软件。
优点
-
抗负载能力强
、是工作在网络4层之上仅作分发之用,没有流量的产生
,这个特点也决定了它在负载均衡软件里的性能最强的; - 配置性比较低,这是一个缺点也是一个优点,因为没有可太多配置的东西,所以并不需要太多接触,大大减少了人为出错的几率;
-
工作稳定,自身有完整的双机热备方案
,如LVS+Keepalived和LVS+Heartbeat,不过我们在项目实施中用得最多的还是LVS/DR+Keepalived; - 无流量,保证了均衡器IO的性能不会收到大流量的影响;
- 应用范围比较广,可以对所有应用做负载均衡;
- 如果是网站应用比较庞大的话,实施LVS/DR+Keepalived起来就比较复杂了,特别后面有Windows Server应用的机器的话,如果实施及配置还有维护过程就比较复杂了,相对而言,Nginx/HAProxy+Keepalived就简单多了。
缺点
- 软件本身
不支持正则表达式处理,不能做动静分离
;而现在许多网站在这方面都有较强的需求,这个是Nginx/HAProxy+Keepalived的优势所在。 - 如果是网站应用比较庞大的话,LVS/DR+Keepalived实施起来就比较复杂了,特别后面有Windows Server的机器的话,如果实施及配置还有维护过程就比较复杂了,相对而言,Nginx/HAProxy+Keepalived就简单多了。
2.2 Nginx
优点
- 工作在网络的7层之上,可以针对http应用做一些分流的策略,比如针对域名、目录结构,它的正则规则比HAProxy更为强大和灵活,这也是许多朋友喜欢它的原因之一;
- Nginx对网络的依赖非常小,理论上能ping通就就能进行负载功能,这个也是它的优势所在;
- Nginx安装和配置比较简单,测试起来比较方便;
- 也可以承担高的负载压力且稳定,一般能支撑超过几万次的并发量;
- Nginx可以通过端口检测到服务器内部的故障,比如根据服务器处理网页返回的状态码、超时等等,并且会把返回错误的请求重新提交到另一个节点,不过其中缺点就是不支持url来检测;
- Nginx仅能支持http和Email,这样就在适用范围上面小很多,这个它的弱势;
- Nginx不仅仅是一款优秀的负载均衡器/反向代理软件,它同时也是功能强大的Web应用服务器。LNMP现在也是非常流行的web架构,大有和以前最流行的LAMP架构分庭抗争之势,在高流量的环境中也有很好的效果。
- Nginx现在作为Web反向加速缓存越来越成熟了,很多朋友都已在生产环境下投入生产了,而且反映效果不错,速度比传统的Squid服务器更快,有兴趣的朋友可以考虑用其作为反向代理加速器。
缺点
- Nginx仅能支持http、https和Email协议,这样就在适用范围上面小些,这个是它的缺点。
- 对后端服务器的健康检查,只支持通过端口来检测,不支持通过url来检测。不支持Session的直接保持,但能通过ip_hash来解决。
3. 常用的开源反向代理软件
3.1 Haproxy
优点
- HAProxy是支持虚拟主机的,以前有朋友说这个不支持虚拟主机,我这里特此更正一下。
- 能够补充Nginx的一些缺点比如Session的保持,Cookie的引导等工作
- 支持url检测后端的服务器出问题的检测会有很好的帮助。
- 它跟LVS一样,本身仅仅就只是一款负载均衡软件;单纯从效率上来讲HAProxy更会比Nginx有更出色的负载均衡速度,在并发处理上也是优于Nginx的。
- HAProxy可以对Mysql读进行负载均衡,对后端的MySQL节点进行检测和负载均衡,不过在后端的MySQL slaves数量超过10台时性能不如LVS,所以我向大家推荐LVS+Keepalived。
- HAProxy的算法现在也越来越多了,具体有如下8种:
①roundrobin,表示简单的轮询,这个不多说,这个是负载均衡基本都具备的;
②static-rr,表示根据权重,建议关注;
③leastconn,表示最少连接者先处理,建议关注;
④source,表示根据请求源IP,这个跟Nginx的IP_hash机制类似,我们用其作为解决session问题的一种方法,建议关注;
⑤ri,表示根据请求的URI;
⑥rl_param,表示根据请求的URl参数'balance url_param' requires an URL parameter name;
⑦hdr(name),表示根据HTTP请求头来锁定每一次HTTP请求;
⑧rdp-cookie(name),表示根据据cookie(name)来锁定并哈希每一次TCP请求。
4. 常用的硬件负载均衡
- F5
- Netscalar
- Radware
- A10
小结
一般对负载均衡的使用是随着网站规模的提升根据不同的阶段来使用不同的技术。具体的应用需求还得具体分析,如果是中小型的Web应用,比如日PV小于1000万,用Nginx就完全可以了;如果机器不少,可以用DNS轮询,LVS所耗费的机器还是比较多的;大型网站或重要的服务,且服务器比较多时,可以考虑用LVS。
一种是通过硬件来进行,常见的硬件有比较昂贵的F5和Array等商用的负载均衡器,它的优点就是有专业的维护团队来对这些服务进行维护、缺点就是花销太大,所以对于规模较小的网络服务来说暂时还没有需要使用;另外一种就是类似于Nginx/LVS/HAProxy的基于Linux的开源免费的负载均衡软件,这些都是通过软件级别来实现,所以费用非常低廉。
目前关于网站架构一般比较合理流行的架构方案:Web前端采用Nginx/HAProxy+Keepalived作负载均衡器;后端采用MySQL数据库一主多从和读写分离,采用LVS+Keepalived的架构。当然要根据项目具体需求制定方案。
下面说说各自的特点和适用场合。
5. Nginx和LVS对比
1、Nginx工作在网络的7层,所以它可以针对http应用本身来做分流策略,比如针对域名、目录结构等,相比之下LVS并不具备这样的功能,所以Nginx单凭这点可利用的场合就远多于LVS了;但Nginx有用的这些功能使其可调整度要高于LVS,所以经常要去触碰触碰,触碰多了,人为出问题的几率也就会大。
2、Nginx对网络稳定性的依赖较小,理论上只要ping得通,网页访问正常,Nginx就能连得通,这是Nginx的一大优势!Nginx同时还能区分内外网,如果是同时拥有内外网的节点,就相当于单机拥有了备份线路;LVS就比较依赖于网络环境,目前来看服务器在同一网段内并且LVS使用direct方式分流,效果较能得到保证。另外注意,LVS需要向托管商至少申请多一个ip来做Visual IP,貌似是不能用本身的IP来做VIP的。要做好LVS管理员,确实得跟进学习很多有关网络通信方面的知识,就不再是一个HTTP那么简单了。
3、Nginx安装和配置比较简单,测试起来也很方便,因为它基本能把错误用日志打印出来。LVS的安装和配置、测试就要花比较长的时间了;LVS对网络依赖比较大,很多时候不能配置成功都是因为网络问题而不是配置问题,出了问题要解决也相应的会麻烦得多。
4、Nginx也同样能承受很高负载且稳定,但负载度和稳定度差LVS还有几个等级:Nginx处理所有流量所以受限于机器IO和配置;本身的bug也还是难以避免的。
5、Nginx可以检测到服务器内部的故障,比如根据服务器处理网页返回的状态码、超时等等,并且会把返回错误的请求重新提交到另一个节点。目前LVS中 ldirectd也能支持针对服务器内部的情况来监控,但LVS的原理使其不能重发请求。比如用户正在上传一个文件,而处理该上传的节点刚好在上传过程中出现故障,Nginx会把上传切到另一台服务器重新处理,而LVS就直接断掉了,如果是上传一个很大的文件或者很重要的文件的话,用户可能会因此而恼火。
6、Nginx对请求的异步处理可以帮助节点服务器减轻负载,假如使用apache直接对外服务,那么出现很多的窄带链接时apache服务器将会占用大 量内存而不能释放,使用多一个Nginx做apache代理的话,这些窄带链接会被Nginx挡住,apache上就不会堆积过多的请求,这样就减少了相当多的资源占用。这点使用squid也有相同的作用,即使squid本身配置为不缓存,对apache还是有很大帮助的。
7、Nginx能支持http、https和email(email的功能比较少用),LVS所支持的应用在这点上会比Nginx更多。在使用上,一般最前端所采取的策略应是LVS,也就是DNS的指向应为LVS均衡器,LVS的优点令它非常适合做这个任务。重要的ip地址,最好交由LVS托管,比如数据库的 ip、webservice服务器的ip等等,这些ip地址随着时间推移,使用面会越来越大,如果更换ip则故障会接踵而至。所以将这些重要ip交给 LVS托管是最为稳妥的,这样做的唯一缺点是需要的VIP数量会比较多。Nginx可作为LVS节点机器使用,一是可以利用Nginx的功能,二是可以利用Nginx的性能。当然这一层面也可以直接使用squid,squid的功能方面就比Nginx弱不少了,性能上也有所逊色于Nginx。Nginx也可作为中层代理使用,这一层面Nginx基本上无对手,唯一可以撼动Nginx的就只有lighttpd了,不过lighttpd目前还没有能做到 Nginx完全的功能,配置也不那么清晰易读。另外,中层代理的IP也是重要的,所以中层代理也拥有一个VIP和LVS是最完美的方案了。具体的应用还得具体分析,如果是比较小的网站(日PV小于1000万),用Nginx就完全可以了,如果机器也不少,可以用DNS轮询,LVS所耗费的机器还是比较多的;大型网站或者重要的服务,机器不发愁的时候,要多多考虑利用LVS。
现在对网络负载均衡的使用是随着网站规模的提升根据不同的阶段来使用不同的技术:
第一阶段:利用Nginx或HAProxy进行单点的负载均衡,这一阶段服务器规模刚脱离开单服务器、单数据库的模式,需要一定的负载均衡,但是仍然规模较小没有专业的维护团队来进行维护,也没有需要进行大规模的网站部署。这样利用Nginx或HAproxy就是第一选择,此时这些东西上手快, 配置容易,在七层之上利用HTTP协议就可以。这时是第一选择。
第二阶段:随着网络服务进一步扩大,这时单点的Nginx已经不能满足,这时使用LVS或者商用Array就是首要选择,Nginx此时就作为LVS或者Array的节点来使用,具体LVS或Array的是选择是根据公司规模和预算来选择,Array的应用交付功能非常强大,本人在某项目中使用过,性价比也远高于F5,商用首选!但是一般来说这阶段相关人才跟不上业务的提升,所以购买商业负载均衡已经成为了必经之路。
第三阶段:这时网络服务已经成为主流产品,此时随着公司知名度也进一步扩展,相关人才的能力以及数量也随之提升,这时无论从开发适合自身产品的定制,以及降低成本来讲开源的LVS,已经成为首选,这时LVS会成为主流。
最终形成比较理想的基本架构为:Array/LVS — Nginx/Haproxy — Squid/Varnish — AppServer。
6. Nginx负载均衡组件说明
- ngx_http_proxy_module
proxy代理模块,用于把请求后抛给服务器节点或upstream服务器池 - ngx_http_upstream_module
负载均衡模块,可以实现网站的负载均衡功能及节点的健康检查
7. 部署
7.1 环境
[root@lb02 ~]# cat /etc/redhat-release
CentOS release 6.7 (Final)
[root@lb02 ~]# uname -r
2.6.32-573.el6.x86_64
[root@lb02 ~]# uname -m
x86_64
[root@lb02 ~]# /etc/init.d/iptables stop
[root@lb02 ~]# getenforce
Disabled
7.2 规划
主机名 | IP | 说明 |
---|---|---|
lb01 | 10.0.0.5 | 负载 |
web01 | 10.0.0.8 | web01服务器 |
web02 | 10.0.0.7 | web02服务器 |
7.3 lb01安装
yum install pcre pcre-devel -y
yum install openssl openssl-devel -y
useradd www -s /sbin/nologin -M
mkdir -p /application/nginx-1.6.3
mkdir -p /home/oldboy/tools
cd /home/oldboy/tools
wget -q http://nginx.org/download/nginx-1.6.3.tar.gz
tar xf nginx-1.6.3.tar.gz
cd nginx-1.6.3
./configure --prefix=/application/nginx-1.6.3 --user=www --group=www --with-http_stub_status_module --with-http_ssl_module
make
make install
ln -s /application/nginx-1.6.3/ /application/nginx
/application/nginx/sbin/nginx
netstat -lntup|grep nginx
echo "/application/nginx/sbin/nginx " >>/etc/rc.local
curl -s -o /dev/null -I -w "%{http_code}\n" 127.0.0.1
cd /application/nginx
egrep -v "#|^$" conf/nginx.conf.default >conf/nginx.conf.bak
sed '10,21d' conf/nginx.conf.bak >conf/nginx.conf
sed -i '9a include extra/www.conf;\ninclude extra/bbs.conf;\ninclude extra/blog.conf;' conf/nginx.conf
mkdir -p conf/extra
sed -n '10,21p' conf/nginx.conf.bak >conf/extra/www.conf
sed -n '10,21p' conf/nginx.conf.bak >conf/extra/bbs.conf
sed -n '10,21p' conf/nginx.conf.bak >conf/extra/blog.conf
sed -i '3s/localhost/www.xindaichina.cn xindaichina.cn/g' conf/extra/www.conf
sed -i '3s/localhost/bbs.xindaichina.cn/g' conf/extra/bbs.conf
sed -i '3s/localhost/blog.xindaichina.cn/g' conf/extra/blog.conf
sed -i '5s#html#/data/www/www#g' conf/extra/www.conf
sed -i '5s#html#/data/www/bbs#g' conf/extra/bbs.conf
sed -i '5s#html#/data/www/blog#g' conf/extra/blog.conf
mkdir -p /data/www/{www,bbs,blog}
echo "www.xindaichina.cn" >/data/www/www/index.html
echo "bbs.xindaichina.cn" >/data/www/bbs/index.html
echo "blog.xindaichina.cn" >/data/www/blog/index.html
/applicaiton/nginx/sbin/nginx -s reload
7.4 Web01和Web02配置
同上述配置
7.5 简单负载均衡实现
修改nginx.conf
轮循
upstream www_server_pools {
server 10.0.0.7:80 weight=1;
server 10.0.0.8:80 weight=1;
}
server {
listen 80;
server_name www.xindaichina.cn;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://www_server_pools;
}
权重轮循
upstream www_server_pools {
server 10.0.0.7:80 weight=1;
server 10.0.0.8:80 weight=2;
}
server {
listen 80;
server_name www.xindaichina.cn;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://www_server_pools;
}
Hash轮循
upstream www_server_pools {
ip_hash;
server 10.0.0.7:80 weight=1;
server 10.0.0.8:80 weight=1;
}
server {
listen 80;
server_name www.xindachina.cn;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://www_server_pools;
}
7.5 测试
curl www.xindaichina.cn
总结
1. 了解软负载的特点
2. 掌握Nginx负载均衡的实现