前言
到现在,Nginx已经占据了 Web 服务器的大壁江山,并且还在不断地增长,比如国内的 BATJ、网易、新浪等公司都可以看到它的身影。
时常浏览某个网站且他发生404错误时,大部分都是Nginx的默认页面,所以对于Nginx,我们还需要继续深造一下。对于本章,将讨论一下Nginx的负载均衡策略以及原理。
负载均衡策略有哪些?
在此之前,先说说为什么要进行负载均衡,由于一台服务器能处理的并发数是有限的,如Tomcat,在默认情况下是150个线程来处理并发任务,如果短时间超出150人访问呢?那么此时很多用户就需要排队等待系统响应。当然这个值我们可以进行改动,但是不是越大越好,小了也不行。
于是乎,我们加入负载均衡,将用户请求分配到不同的服务器进行处理,假设1台服务器可以处理150个请求,5台就能处理150*5=750个请求,这样就大大提高了系统处理业务的能力,如下图所示。
但现在的问题是,Nginx如何把请求分配到不同的Tomcat中,又是个学问,不能让某个Tomcat一直忙的,而其他Tomcat在旁边喝茶,非气死不可,在这里我们自己想一下,到底该怎么做呢。
Nginx的自白
我叫Nginx,在我背后藏着很多Tomcat(别惹我哟),他们正等着我分配用户打赏的小费,但是我面临这一个问题,怎么把这些小费分到不同Tomcat手中呢?于是我苦思冥想了几秒钟,发现很伤脑筋,算了,不想了,还是找我的哥们apache、IIS打牌吧。
等等,打牌?我想到了,我可以借用发牌的思想,轮询分配给Tomcat,也就是第一个请求给Tomcat-A,第二个给Tomcat-B,…,第四个给Tomcat-D,第5个给Tomcat-A,哈哈,完美,还很公平。我忍不住要给他起个名字,就叫轮询策略吧。
只要给我简单配置一下,我就可以这样工作。并且我总结了一句话,轮询策略指每次将请求按顺序轮流发送至相应的服务器上
upstream bakend {
server 192.168.1.10;
server 192.168.1.11;
}
server {
listen 80;
location / {
proxy_pass http://bakend;
}
}
这真是太棒了。
但是好景不长,这种模式我发现一个问题,由于Tomcat被打赏小费后,会花一些时间把小费装钱包里,这就导致如Tomcat-A还没来得及装钱包里,又轮到给他打赏了,最终导致越来越多的小费,他来不及装,部分被掉在地上。
不行,我要在想一种办法。
为什么不把小费分给正在空闲或者不太拥挤的Tomcat呢,对,就是这样,我记录每个Tomcat要装小费的次数,选取最少的那个进行分配。
只需这样配置我即可,我起名叫他最少连接数负载均衡,指每次将请求分发到当前连接数最少的服务器上,也就是我将请求转发给相对空闲的服务器以实现负载平衡。
upstream myapp1 {
least_conn;
server srv1.example.com;
server srv2.example.com;
server srv3.example.com;
}
我真是太聪明了。
但是后来,我发现某些Tomcat特别壮,很肥很肥,他装小费的速度很快,那我为什么不能多给他分配点请求呢?谁让他处理的快呢,能者多劳嘛。
通过以下配置,如果有5 次请求,将有3次请求会分发给 srv1,1次请求会分发给srv2,另外 1次请求会分发给 srv3。我起名叫他加权负载均衡
upstream myapp1 {
server srv1.example.com weight=3;
server srv2.example.com;
server srv3.example.com;
}
但是问题又来了,用户A第一次请求把一些信息放入到Tomcat-A中,他说,下一次我还要访问Tomcat-A,其他Tomcat中没有我信息。但是根据我目前所有的分配策略来看,这似乎又是一个问题,该怎么办呢?
于是我查阅了大量资料,发现hash函数非常有意思,学以致用,我可以以根据客户端的 IP,通过hash函数,就可以将其固定的分配到相应的服务器上。
就叫他ip-hash 负载均衡吧。
upstream myapp1 {
ip_hash;
server srv1.example.com;
server srv2.example.com;
server srv3.example.com;
}