nginx 负载均衡两台服务器 nginx负载均衡不如单机_负载均衡


引言

对于应用程序来说,随着数据量与访问量越来越大,传统的单体架构往往已经不能满足高负载,高并发的需求了。架构往往会由最初的单体架构,演变为高可用的架构。那么,负载均衡几乎又是其架构中必不可少的一部分。

nginx 负载均衡器的使用

由于nginx 的epoll 工作模式,使得nginx有着单机就可以抗高并发的能力(相比于另外一款web服务器apache来说),但是,nginx的稳定性又比apache差,因此,实际工作中,往往是nginx作为前端代理,转发请求到apache集群中,这就是nginx作为负载均衡器的使用初衷。

nginx 负载均衡的几种算法

例如,如果apache集群中,有5台服务器,那么,nginx服务器应该将请求转发在哪台服务器呢,这就是由以下要介绍的几种负载均衡的算法的决定的。

  • 简单轮询

如图:


nginx 负载均衡两台服务器 nginx负载均衡不如单机_负载均衡的几种方式_02


顾名思义,这个方法是对后端web服务器进行简单的轮询,将请求按顺序发给后端服务器。但是,每台后端服务器,也许使用时间、硬件、软件配置都不相同,这也就导致每台服务器的性能也许就大不相同,每个服务器此刻处理的请求数量也是不一样的,这样简单地轮询,真正线上使用,不推介使用此种方式。

  • 加权轮询法

如图:


nginx 负载均衡两台服务器 nginx负载均衡不如单机_服务器_03


简单的轮询法并不考虑后端机器的性能和负载差异。加权轮询就是为每一台服务器加一个权重(通俗的理解就是一个比例),按处理能力强的配置权重大,处理能力弱的配置权重低原则,进行合理分配。

  • 随机算法

该算法就是每来一个请求,从后端服务器中随机地选择一个服务器处理请求

  • 源地址哈希法

该方法是对客户端的IP地址做一个Hash,然后对服务器列表的大小取模,得到处理该请求的服务器,采用源地址哈希法进行负载均衡,相同的IP客户端,如果服务器列表不变,将映射到同一个后台服务器进行访问

  • 最小连接法

如图:


nginx 负载均衡两台服务器 nginx负载均衡不如单机_负载均衡_04


该算法是检测哪一台服务器上的连接数最小,就将请求发给那一台服务器

示例

在nginx.conf 中可以进行相关配置,以下只进行简单举例:

1、在http节点下,添加upstream节点。

upstream swoole_server{ 
 server 192.168.137.101:8081; 
 server 192.168.137.102:8081; 
 server 192.168.137.103:8081;
}

参数说明: 其中upstream 是固定写法,swoole_server 是自己定义的集群服务名称(个人理解),这个名称可以随便定义(只要合法即可)。其中配置了3台服务器,我这里带上了端口访问。

2、将server节点下的location节点中的proxy_pass配置为:http:// + swoole_server名称,即“ http://swoole_server”.

location / { 
 root html; 
 index index.html index.htm; 
 proxy_pass http://swoole_server; 
}

简单负载均衡初步完成了。upstream按照轮询(默认)方式进行负载,每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。虽然这种方式比较简单,但是最主要是负载分配不均衡。

如果进行权重分配,就如下

upstream swoole_server{ 
 server 192.168.137.101:8081 weight=5; 
 server 192.168.137.102:8081 weight=5;
 server 192.168.137.103:8081 weight=10;
}

weight 就是权重配置,自己依照服务器性能进行合理配置即可。

如果进行ip_hash分配,就如下:

upstream swoole_server{ 
 ip_hash; 
 server 192.168.137.101:8081; 
 server 192.168.137.102:8081;
 server 192.168.137.103:8081;
}

此种方式,每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。

还有一些配置项,大家共同探讨吧。

结语

nginx 作为一款优秀的web服务器,有着其显而易见的优势,大家可以合理使用。负载均衡的另外一个问题,在于session存储,例如,a用户第一次请求是转发在了a服务器上,如果使用默认的本地文件方式存放session,那么a用户的session 信息就写入了a服务器本地文件,如果a用户的第二次请求落在了b服务器上,那么b服务器本地文件并没有a用户的session信息,这就会导致一系列的问题,因此解决session 共享也是一个难题,例如session存储可以使用user的方式,将session放在redis集群中,apache集群,共同访问redis集群中的session 信息,即使a服务器挂掉,a用户也不会被强制退出。因为session会存在大量读取问题,不建议放在数据库中。完!!!