nginx系列之实现简单的负载均衡

本文介绍了如何使用nginx实现负载均衡,包括轮询方法、带权重的轮询和ip_hash策略。通过实例展示了配置过程和测试结果,帮助理解nginx在负载均衡中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、前言

负载均衡,个人理解,旨在于把客户端的请求均匀地发到后端服务器来处理,以解决单机处理能力有限的问题,同时又不让某个服务器负担过重。

百度一下“负载均衡”,文章一大把,不过别人怎么说与自己怎么做是两回事。通常使用的负载均衡的软件有LVS、HAProxy和nginx,其中nginx配置比较简单,手边也正好有这个软件,于是想用nginx来练习下。

用nginx实现负载均主要使用upstream和proxy这个两个模块。目前nginx的负载均衡有轮询、ip _hash(按照客户段ip地址来分配)、least_conn(优先选择活动连接数最少的上游服务器)、least_time(优先选择处理时间最短的上游服务器)这4种方法,默认是轮询,可以带权重。

二、环境搭建与测试

笔者用的是OpenResty,主要是因为第三方模块众多,其中用echo模块的echo指令可以直接向客户端输出内容,使得调试方便不少。

环境搭建得益于nginx命令的 -c 选项,该选项可以让nginx以不同的配置文件启动。本次测试在一台个人笔记本中进行,共开启4个nginx服务主进程,其中1个监听在80端口,作为负载均衡器。另外3个分别监听8001、8002、8003端口,分别命名为server-8001、server-8002、server-8003,作为上游服务器。

2.1 轮询方法
  • 负载均衡器的配置
    upstream @backend {
        server 127.0.0.1:8001;
        server 127.0.0.1:8002;
        server 127.0.0.1:8003;
    }

将该配置置于http上下文中。
该配置定义了一组服务器组,命名为@backend。默认是轮询方式,请求是平均分给每一个上游服务器的。

location / {
   proxy_set_header Host $host;
   proxy_set_header X-Real-IP $remote_addr;
   proxy_pass http://@backend;
}

将该配置置于server上下文中。
proxy_set_header指令的作用是设置传给上游服务器的请求头,proxy_set_header Host $host 的作用是让上游服务器获取到客户端请求的真实“Host” HTTP请求头 。proxy_set_header X-Real-IP $remote_addr的作用是让上游服务器获取到真实的客户端地址,否则获取到的都是代理服务器的地址。
proxy_pass http://@backend,把请求传给上游服务器组@backend处理。

  • 上游服务器的配置
server {
    listen       8001;
    server_name  localhost;
    location / {
        default_type text/html;
        # 用$server_port来区分到底访问的是哪个上游服务器
        echo "Serving at $server_port";
    }

保存与于conf目录下,命名为server-8001.conf。分别用8002、8003替换8001,保存为server-8002.conf, server-8003.conf。

测试:
第一步:打开命令行,切换到nginx安装目录,输入两次 “start” 命令,这样有3个相同路径的命令行窗口了。
第二步:启动上游服务器,分别在3个命令行窗口输入:

nginx -c conf/server-8001.conf
nginx -c conf/server-8002.conf
nginx -c conf/server-8003.conf

第三步:启动负载均衡器,打开浏览器,访问 localhost,刷新8次。
结果如下:

Serving at 8001
Serving at 8003
Serving at 8002
Serving at 8001
Serving at 8003
Serving at 8002
Serving at 8001
Serving at 8003
Serving at 8002

共9次请求,依次按server-8001、server-8003、server-8002顺序把请求分配到上游服务器,的确是轮询方法。

要使请求不分配给某台上游服务器,可以在upstream上下文中的server指令后面增加down参数。如:

upstream @backend {
    server 127.0.0.1:8001 down;
    server 127.0.0.1:8002;
    server 127.0.0.1:8003;
}

该配置使得请求不分配给server-8001。
重启服务器,在浏览器中访问localhost,刷新几次,可以看到,输出的不是 “Serving at 8003” 就是 “Serving at 8002”,server-8001并未收到任何请求。

2.2 带权重的轮询

带权重的轮询主要用于上游服务器性能不一样的情况,默认权重都是1。可以给性能好的服务器设置大一点的权重,性能差的服务器设置小一点的权重。

把负载均衡器的upstream指令改为如下:

upstream @backend {
    server 127.0.0.1:8001 weight=3;
    server 127.0.0.1:8002;
    server 127.0.0.1:8003;
}

该配置的功能是把服务器8001的权重设为3,也就是说,平均每5个请求,3个分配给服务器8001,另外2个平均分配给剩下的服务器。

重启服务器,用以下PHP脚本测试:

$count = 0;
$result = [];
while ($count++ < 15) {
    $content = trim(file_get_contents("http://localhost/"));
    isset($result[$content]) ? $result[$content]++ : $result[$content] = 1;
    echo $content, PHP_EOL;
}

foreach ($result as $k => $v) {
    echo $k, ' => ', $v, PHP_EOL;
}

输出:

Serving at 8001
Serving at 8002
Serving at 8001
Serving at 8003
Serving at 8001
Serving at 8001
Serving at 8002
Serving at 8001
Serving at 8003
Serving at 8001
Serving at 8001
Serving at 8002
Serving at 8001
Serving at 8003
Serving at 8001
Serving at 8001 => 9
Serving at 8002 => 3
Serving at 8003 => 3

共15次请求,每5次请求,3个分配给了server-8001,1个分配给了server-8002, 1个分配给了server-8003。三个服务器分配到请求的比例是3:1:1,跟负载均衡器配置的一样。

2.3 按ip分配(ip_hash)

按ip分配要用到ip_hash指令,使得同一个ip的请求会分配到相同的上游服务器。用于解决Session/Cookie共享问题。
把负载均衡器的upstream指令改为如下:

upstream @backend {
    ip_hash;
    server 127.0.0.1:8001;
    server 127.0.0.1:8002;
    server 127.0.0.1:8003;
}

重启服务器,用浏览器多次访问localhost,都是输出:

Serving at 8003

本地测试,ip地址是127.0.0.1,负载均衡器把请求都分配给了sever-8003。

另外还有2个负载均衡方式是最少连接数和最短请求处理时间,分别对应指令least_conn、least_time,有时间再做测试。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值