一:为什么要实现负载均衡
当一台服务器的单位时间内访问量越大的时候,服务器压力会越大,当一台服务器压力大得超过自身的承受压力的时候,服务器会崩溃。为了避免服务器崩溃,让用户更好的体验,我们通常通过负载均衡的方式来分担服务器的压力。那么什么是负载均衡呢?我们可以建立很多个服务器,这些服务器组成一个服务器集群,然后当用户访问我们的网站的时候,先访问一个中间服务器,再让这个中间服务器在服务器群中选择一个压力较小的服务器,然后将该访问请求引入选择的服务器。这样,用户每次的访问,都会保证服务器集群中的每个服务器的压力区域平衡,分担了服务器的压力,避免了服务器崩溃的情况。
二:Nginx的优势
nginx是一款可以通过反向代理实现负载均衡的服务器,使用nginx服务器实现负载均衡的时候,用户首先会访问到nginx服务器,然后nginx服务器再从服务器群中选择压力较小的服务器,把该访问请求引入到该服务器。若服务器群中的某个服务器崩溃,那么从待选的服务器列表中删除,也就是说如果一个服务器崩溃了,那么nginx肯定不会把访问引入该服务器了。
三:负载均衡
当使用了代理服务器时,一般代理服务器后面不仅仅只有一台原始服务器,而是有很多台服务器一起在处理用户发过来的请求,这时就要协调好多台服务器怎样合作共同处理用户的请求
若所有的原始服务器配置相差不大的情况下,负载均衡的手段一般为轮询,即每台服务器平等地处理用户的请求,当请求到来时会自动交给当前所负责事务最少的服务器去处理;
若原始服务器的配置有一定差异时,则采用加权轮询的方式,配置较好的服务器将负责更多的请求处理,反之亦然;
而一旦采取轮询方式,而要考虑session共享的问题,因为要是用户的请求被分配给不同的服务器处理而未实现session共享的话则需要用户重复登陆操作,当前实现session共享的方式有写入数据库或者写入memcached;
若不想处理session共享,则采用ip哈希的方式将某一用户的请求指定分配给某一台服务器,在配置中加上 ip_hash 这句即可;
几种常用的负载均衡方式
最少连接:系统把新连接分配给当前连接数目最少的服务器。该算法在各个服务器运算能力基本相似的环境中非常有效。
最快算法:最快算法基于所有服务器中的最快响应时间分配连接。该算法在服务器跨不同网络的环境中特别有用。
轮询:轮询算法按顺序把每个新的连接请求分配给下一个服务器,最终把所有请求平分给所有的服务器。轮询算法在大多数情况下都工作的不错,但是如果负载均衡的设备在处理速度、连接速度和内存等方面不是完全均等,那么效果会更好。
加权轮询:该算法中,每个机器接受的连接数量是按权重比例分配的。这是对普通轮询算法的改进,比如你可以设定:第三台机器的处理能力是第一台机器的两倍,那么负载均衡器会把两倍的连接数量分配给第3台机器。
Nginx负载均衡部署
测试环境:
由于没有服务器,所以本次测试直接host指定域名,然后在VMware里安装了三台CentOS。
测试域名 :a.com
A服务器IP :172.16.253.89 (主)
B服务器IP :172.16.253.88
C服务器IP :172.16.251.82
部署思路:
A服务器做为主服务器,域名直接解析到A服务器(172.16.253.89)上,由A服务器负载均衡到B服务器(172.16.253.88)与C服务器(172.16.251.82)上。
1: 域名解析
由于不是真实环境,域名就随便使用一个a.com用作测试,所以a.com的解析只能在hosts文件设置。
打开:C:\Windows\System32\drivers\etc\hosts
在末尾添加:
172.16.253.89 a.com
保存退出,然后启动命令模式ping下看看是否已设置成功
从截图上看已成功将a.com解析到172.16.253.89
2: A服务器nginx.conf设置
打开nginx.conf,文件位置在nginx安装目录的conf目录下。(yum安装的话在/etc/nginx/nginx.conf下)
在http段加入以下代码:
upstream a.com {
server 172.16.253.88:80;
server 172.16.251.82:80;
}
server{
listen 80;
server_name a.com;
location / {
proxy_pass http://a.com;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
3:B、C服务器nginx.conf设置:
打开nginx.conf,在http段加入以下代码
server{
listen 80;
server_name a.com;
index index.html;
root /var/www/html/;
}
保存重启nginx
我在重启的过程中遇到了如下错误提示,原来是80端口被占用。使用下面命令就可以解决问题了。
4:测试
当访问a.com的时候,为了区分是转向哪台服务器处理我分别在B、C服务器下写一个不同内容的index.html文件,以作区分。
编辑各自的index.html文件
vim /var/www/html/index.html
打开浏览器访问a.com结果,刷新会发现所有的请求均分别被主服务器(172.16.253.89)分配到B服务器(172.16.253.88)与C服务器(172.16.251.82)上,实现了负载均衡效果。
B服务器处理页面
C服务器处理页面(要是出不来此结果可以换个浏览器试试,因为访问过之后可能会有缓存)
5:假如其中一台服务器宕机会怎样?
当某台服务器宕机了,是否会影响访问呢?
我们先来看看实例,根据以上例子,假设C服务器172.16.251.82 这台机子宕机了(由于无法模拟宕机,所以我就把C服务器关机)然后再来访问看看。
访问结果:
我们发现,虽然C服务器(172.16.251.82)宕机了,但不影响网站访问。这样,就不会担心在负载均衡模式下因为某台机子宕机而拖累整个站点了。
6: 主服务器不能提供服务吗?
以上例子中,我们都是应用到了主服务器负载均衡到其它服务器上,那么主服务器本身能不能也加在服务器列表中,这样就不会白白浪费拿一台服务器纯当做转发功能,而是也参与到提供服务中来。
如以上案例三台服务器:
A服务器IP :172.16.253.89(主)
B服务器IP :172.16.253.88
C服务器IP :172.16.251.82
我们把域名解析到A服务器,然后由A服务器转发到B服务器与C服务器,那么A服务器只做一个转发功能,现在我们让A服务器也提供站点服务。
我们先来分析一下,如果添加主服务器到upstream中,那么可能会有以下两种情况发生:
1、主服务器转发到了其它IP上,其它IP服务器正常处理;
2、主服务器转发到了自己IP上,然后又进到主服务器分配IP那里,假如一直分配到本机,则会造成一个死循环。
怎么解决这个问题呢?因为80端口已经用来监听负载均衡的处理,那么本服务器上就不能再使用80端口来处理a.com的访问请求,得用一个新的。于是我们把主服务器的/etc/nginx/nginx.conf加入以下一段代码:
server{
listen 8080;
server_name a.com;
index index.html;
root /var/www/html/;
}
重启nginx,在浏览器输入a.com:8080试试看能不能访问。结果可以正常访问
既然能正常访问,那么我们就可以把主服务器添加到upstream中,但是端口要改一下,如下代码(编辑主服务器的此文件vim /etc/nginx/nginx.html):
upstream a.com {
server 172.16.253.88:80;
server 172.16.251.82:80;
server 172.16.253.89:8080;
}
由于这里可以添加主服务器IP172.16.253.89 或者127.0.0.1均可以,都表示访问自己。
重启Nginx,然后再来访问a.com看看会不会分配到主服务器上。
主服务器也能正常加入服务了。
总结:
一、负载均衡不是nginx独有,著名鼎鼎的apache也有,但性能可能不如nginx。
二、多台服务器提供服务,但域名只解析到主服务器,而真正的服务器IP不会被ping下即可获得,增加一定安全性。
三、upstream里的IP不一定是内网,外网IP也可以。不过经典的案例是,局域网中某台IP暴露在外网下,域名直接解析到此IP。然后又这台主服务器转发到内网服务器IP中。
四、某台服务器宕机、不会影响网站正常运行,Nginx不会把请求转发到已宕机的IP上