Nginx负载均衡配置

随着网站访问量的增长,一台web服务器可能扛不住日益增长的流量压力,为了缓解压力,可以增加服务器硬件配置(不可靠),我们可以将压力分散到不同的多台服务器上,实现负载均衡。本文给大家介绍Nginx负载均衡配置以及实验测试。

负载均衡模块Upstream

Upstream是Nginx的HTTP Upstream模块,这个模块通过一个简单的调度算法来实现客户端IP到后端服务器的负载均衡。

upstream webhost 
{
  ip_hash;
  server 192.168.11.31;
  server 192.168.11.32 max_fails=3  fail_timeout=20s;
}
知识兔

在上面的设定中,通过upstream指令指定了一个负载均衡器的名称webhost。这个名称可以任意指定,在后面需要用到的地方直接调用即可。

Upstream模块支持的负载均衡策略

Nginx的Upstream负载均衡模块目前支持以下常用的策略算法:

轮询:这是默认的策略,每个请求按时间顺序逐一分配到不同的后端服务器,如果后端某台服务器宕机,故障系统被自动剔除,使用户访问不受影响。

upstream webhost 
{
  server 192.168.11.31;
  server 192.168.11.32;
}
知识兔

权重:weight默认值为1,值越大则代表被访问的几率越大,主要用于后端每个服务器性能不均的情况下。如下配置,32的访问数量是31的2倍

upstream webhost 
{
  server 192.168.11.31 weight=1;
  server 192.168.11.32 weight=2;
}
知识兔

ip_hash:根据访问客户端ip的hash值分配,这样同一客户端的请求都会被分配到同一个server上,如果牵扯到session的问题,比如记录用户登录状态,用这个是最好的选择,可保证每次请求都是同一个session,规避不同服务器间session共享问题。

upstream webhost 
{
  ip_hash;
  server 192.168.11.31;
  server 192.168.11.32;
}
知识兔

状态参数

在HTTP Upstream模块中,可以通过server指令指定后端服务器的IP地址和端口,同时还可以设定每个后端服务器在负载均衡调度中的状态。常用的状态有:

down:表示当前的server暂时不参与负载均衡。

backup:预留的备份机器。当其他所有的非backup机器出现故障或者忙的时候,才会请求backup机器,因此这台机器的压力最轻。

max_fails:允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误。

fail_timeout:在经历了max_fails次失败后,暂停服务的时间。max_fails可以和fail_timeout一起使用。

注意,当负载调度算法为ip_hash时,后端服务器在负载均衡调度中的状态不能是weightbackup

实验测试

学习了Upstream模块相关知识后,我们接下来开始动手实验测试。

1、准备实验环境
  • 域名:mytest.net
  • 服务器系统:Centos7.2、nginx/1.12.2
  • 1号服务器:192.168.11.31
  • 2号服务器:192.168.11.32
  • 3号服务器:192.168.11.34

准备3台虚拟机服务器,其中3号服务器用来做负载均衡配置,绑定域名。1号和2号服务器作为后置服务器用来提供真实数据服务。

2、实验预期效果

我们希望,通过浏览器输入域名mytest.net,刷新页面,可以分别访问到1号服务器和2号服务器上提供的内容,从而实现负载均衡。断开1号和2号服务器中的任意一台,都不会影响用户访问。

3、配置3号服务器

配置nginx。

[root@localhost ~]# vim /usr/local/nginx/conf/vhost/mytest.conf 
upstream webhost 
{
  #ip_hash;
  server 192.168.11.31;
  server 192.168.11.32;
}

server
{
    listen 80;
    server_name mytest.net;
    
    index index.html index.htm;
    root  /home/mytest;
    
    location / 
    {
        proxy_pass http://webhost;
        proxy_redirect off;
        proxy_set_header  X-Real-IP $remote_addr;  #定义请求头中真实IP地址,方便后端被代理服务器获取真实的IP
        proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header  Host $host;
    }
}
知识兔

upstream是定义在server{ }之外的,不能定义在server{ }内部。定义好upstream之后,用proxy_pass引用一下即可。

这里我们还需要注意的是,proxy_set_header用来设置请求头部header,上面的代码中我们设置了头部包含获取客户端真实IP,如果不设置,使用Nginx的负载均衡后,获取的是代理服务器的IP,我们在后面会验证。

编辑好后保存配置文件,并重载nginx使配置生效:

[root@localhost ~]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@localhost ~]# /usr/local/nginx/sbin/nginx -s reload
[root@localhost ~]#
知识兔
4、配置1号和2号服务器

1号和2豪服务器的Nginx配置就和正常站点的配置一样,无需配置Upstream模块,站点配置可参考:《Nginx配置多域名多站点》

为了验证负载均衡的有效性,我们在1号和2号服务器上可以分别加上一段PHP代码,用来响应服务器请求,根据负载分配过来的请求,获取用户的IP以及代理IP等信息:

<?php 
echo '<h1>Server 1.</h1>';

$server = $_SERVER;
echo '访问服务器IP:'. $server['SERVER_ADDR'] . "<br/>";
echo '代理服务器IP:'. $server['REMOTE_ADDR'] . "<br/>";
echo '客户端真实IP:'. $server['HTTP_X_REAL_IP'] . "<br/>";
知识兔
5、验证

最后,我们用浏览器访问域名mytest.net(本机设置好域名指向host文件),得到如下响应:

202203131827030078190000

很显然,我们通过3号服务器访问到了1号服务器的内容,再次刷新,可以访问到2号服务器的内容(本机客户端IP:192.168.11.5)。

202203131827043801830001

我们可以把2号服务器暂时停止服务,尝试访问下域名看看。

不断刷新页面,我们会发现,Server 1和Server 2会交替出现。从实验效果来看,我们已经实现了Nginx的负载均衡功能。实验中,3号服务器起了关键作用,它就像路由器一样,根据负载均衡策略,把用户的请求分配给后端服务器,并把后端服务器的响应传递给客户端。

最后问题来了,假如3号服务器挂了这么办?3号服务器是关键服务器,它挂了就意味着请求得不到响应,当然有解决方案。接下来Helloweba会有文章介绍Keepalive实现高可用。

计算机