阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Nginx 的软件负载均衡详解

286次阅读
没有评论

共计 4628 个字符,预计需要花费 12 分钟才能阅读完成。

负载均衡在服务端开发中算是一个比较重要的特性。因为 Nginx 除了作为常规的 Web 服务器外,还会被大规模的用于反向代理前端,因为 Nginx 的异步框架可以处理很大的并发请求,把这些并发请求 hold 住之后就可以分发给后台服务端 (backend servers,也叫做服务池,后面简称 backend) 来做复杂的计算、处理和响应,这种模式的好处是相当多的:隐藏业务主机更安全,节约了公网 IP 地址,并且在业务量增加的时候可以方便地扩容后台服务器。

负载均衡可以分为硬件负载均衡和软件负载均衡,前者一般是专用的软件和硬件相结合的设备,设备商会提供完整成熟的解决方案,通常也会更加昂贵。软件的负载均衡以 Nginx 占据绝大多数,本文也是基于其手册做相应的学习研究的。

一、基本简介

负载均衡涉及到以下的基础知识。

(1) 负载均衡算法

阿里云 2 核 2G 服务器 3M 带宽 61 元 1 年,有高配

腾讯云新客低至 82 元 / 年,老客户 99 元 / 年

代金券:在阿里云专用满减优惠券

(2) 会话一致性

用户 (浏览器) 在和服务端交互的时候,通常会在本地保存一些信息,而整个过程叫做一个会话 (Session) 并用唯一的 Session ID 进行标识。会话的概念不仅用于购物车这种常见情况,因为 HTTP 协议是无状态的,所以任何需要逻辑上下文的情形都必须使用会话机制,此外 HTTP 客户端也会额外缓存一些数据在本地,这样就可以减少请求提高性能了。如果负载均衡可能将这个会话的请求分配到不同的后台服务端上,这肯定是不合适的,必须通过多个 backend 共享这些数据,效率肯定会很低下,最简单的情况是保证会话一致性——相同的会话每次请求都会被分配到同一个 backend 上去。

(3) 后台服务端的动态配置

出问题的 backend 要能被及时探测并剔除出分配群,而当业务增长的时候可以灵活的添加 backend 数目。此外当前风靡的 Elastic Compute 云计算服务,服务商也应当根据当前负载自动添加和减少 backend 主机。

(4) 基于 DNS 的负载均衡

通常现代的网络服务者一个域名会关连到多个主机,在进行 DNS 查询的时候,默认情况下 DNS 服务器会以 round-robin 形式以不同的顺序返回 IP 地址列表,因此天然将客户请求分配到不同的主机上去。不过这种方式含有固有的缺陷:DNS 不会检查主机和 IP 地址的可访问性,所以分配给客户端的 IP 不确保是可用的(Google 404);DNS 的解析结果会在客户端、多个中间 DNS 服务器不断的缓存,所以 backend 的分配不会那么的理想。

二、Nginx 中的负载均衡

Nginx 中的负载均衡配置在手册中描述的极为细致,此处就不流水帐了。对于常用的 HTTP 负载均衡,主要先定义一个 upstream 作为 backend group,然后通过 proxy_pass/fastcgi_pass 等方式进行转发操作,其中 fastcgi_pass 几乎算是 Nginx+PHP 站点的标配了。

2.1 会话一致性

Nginx 中的会话一致性是通过 sticky 开启的,会话一致性和之前的负载均衡算法之间并不冲突,只是需要在第一次分配之后,该会话的所有请求都分配到那个相同的 backend 上面。目前支持三种模式的会话一致性:

(1). Cookie Insertion
在 backend 第一次 response 之后,会在其头部添加一个 session cookie,即由负载均衡器向客户端植入 cookie,之后客户端接下来的请求都会带有这个 cookie 值,Nginx 可以根据这个 cookie 判断需要转发给哪个 backend 了。

sticky cookie srv_id expires=1h domain=.example.com path=/;

上面的 srv_id 代表了 cookie 的名字,而后面的参数 expires、domain、path 都是可选的。

(2). Sticky Routes
也是在 backend 第一次 response 之后,会产生一个 route 信息,route 信息通常会从 cookie/URI 信息中提取。

route $route_cookie $route_uri;

这样 Nginx 会按照顺序搜索 routecookie、route_uri 参数并选择第一个非空的参数用作 route,而如果所有的参数都是空的,就使用上面默认的负载均衡算法决定请求分发给哪个 backend。

(3). Learn
较为的复杂也较为的智能,Nginx 会自动监测 request 和 response 中的 session 信息,而且通常需要回话一致性的请求、应答中都会带有 session 信息,这和第一种方式相比是不用增加 cookie,而是动态学习已有的 session。

这种方式需要使用到 zone 结构,在 Nginx 中 zone 都是共享内存,可以在多个 worker process 中共享数据用的。(不过其他的会话一致性怎么没用到共享内存区域呢?)

learn 
   create=$upstream_cookie_examplecookie
   lookup=$cookie_examplecookie
   zone=client_sessions:1m
   timeout=1h;
2.2 Session Draining

主要是有需要关闭某些 backend 以便维护或者升级,这些关键性的服务都讲求 gracefully 处理的:就是新的请求不会发送到这个 backend 上面,而之前分配到这个 backend 的会话的后续请求还会继续发送给他,直到这个会话最终完成。

让某个 backend 进入 draining 的状态,既可以直接修改配置文件,然后按照之前的方式通过向 master process 发送信号重新加载配置,也可以采用 Nginx 的 on-the-fly 配置方式。

$ curl http://localhost/upstream_conf?upstream=backend
$ curl http://localhost/upstream_conf?upstream=backend\&id=1\&drain=1

通过上面的方式,先列出各个 bacnkend 的 ID 号,然后 drain 指定 ID 的 backend。通过在线观测 backend 的所有 session 都完成后,该 backend 就可以下线了。

2.3 backend 健康监测

backend 出错会涉及到两个参数,max_fails=1 fail_timeout=10s; 意味着只要 Nginx 向 backend 发送一个请求失败或者没有收到一个响应,就认为该 backend 在接下来的 10s 是不可用的状态。

通过周期性地向 backend 发送特殊的请求,并期盼收到特殊的响应,可以用以确认 backend 是健康可用的状态。通过 health_check 可以做出这个配置。

match server_ok {
    status 200-399;
    header Content-Type = text/html;
    body !~ "maintenance mode";
}
server {
    location / {
        proxy_pass http://backend;
        health_check interval=10 fails=3 passes=2 match=server_ok;
    }
}

上面的 health_check 是必须的,后面的参数都是可选的。尤其是后面的 match 参数,可以自定义服务器健康的条件,包括返回状态码、头部信息、返回 body 等,这些条件是 && 与关系。默认情况下 Nginx 会相隔 interval 的间隔向 backend group 发送一个”/“的请求,如果超时或者返回非 2xx/3xx 的响应码,则认为对应的 backend 是 unhealthy 的,那么 Nginx 会停止向其发送 request 直到下次改 backend 再次通过检查。

在使用了 health_check 功能的时候,一般都需要在 backend group 开辟一个 zone,在共享 backend group 配置的同时,所有 backend 的状态就可以在所有的 worker process 所共享了,否则每个 worker process 独立保存自己的状态检查计数和结果,两种情况会有很大的差异哦。

2.4 通过 DNS 设置 HTTP 负载均衡

Nginx 的 backend group 中的主机可以配置成域名的形式,如果在域名的后面添加 resolve 参数,那么 Nginx 会周期性的解析这个域名,当域名解析的结果发生变化的时候会自动生效而不用重启。

http {
    resolver 10.0.0.1 valid=300s ipv6=off;
    resolver_timeout 10s;
    server {
        location / {proxy_pass http://backend;}
    }
    upstream backend {
        zone backend 32k;
        least_conn;
        ...
        server backend1.example.com resolve;
        server backend2.example.com resolve;
    }
}

如果域名解析的结果含有多个 IP 地址,这些 IP 地址都会保存到配置文件中去,并且这些 IP 都参与到自动负载均衡。

2.5 TCP/UDP 流量的负载均衡

通常,HTTP 和 HTTPS 的负载均衡叫做七层负载均衡,而 TCP 和 UDP 协议的负载均衡叫做四层负载均衡。因为七层负载均衡通常都是 HTTP 和 HTTPS 协议,所以这种负载均衡相当于是四层负载均衡的特例化,均衡器可以根据 HTTP/HTTPS 协议的头部(User-Agent、Language 等)、响应码甚至是响应内容做额外的规则,达到特定条件特定目的的 backend 转发的需求。

除了 Nginx 所专长的 HTTP 负载均衡,Nginx 还支持 TCP 和 UDP 流量的负载均衡,适用于 LDAP/MySQL/RTMP 和 DNS/syslog/RADIUS 各种应用场景。这类情况的负载均衡使用 stream 来配置,Nginx 编译的时候需要支持–with-stream 选项。查看手册,其配置原理和参数和 HTTP 负载均衡差不多。

因为 TCP、UDP 的负载均衡都是针对通用程序的,所以之前 HTTP 协议支持的 match 条件 (status、header、body) 是没法使用的。TCP 和 UDP 的程序可以根据特定的程序,采用 send、expect 的方式来进行动态健康检测。

match http {
    send      "GET / HTTP/1.0\r\nHost: localhost\r\n\r\n";
    expect ~* "200 OK";
}
2.6 其他特性

slow_start=30s:防止新添加 / 恢复的主机被突然增加的请求所压垮,通过这个参数可以让该主机的 weight 从 0 开始慢慢增加到设定值,让其负载有一个缓慢增加的过程。

max_conns=30:可以设置 backend 的最大连接数目,当超过这个数目的时候会被放到 queue 队列中,同时队列的大小和超时参数也可以设置,当队列中的请求数大于设定值,或者超过了 timeout 但是 backend 还不能处理请求,则客户端将会收到一个错误返回。通常来说这还是一个比较重要的参数,因为 Nginx 作为反向代理的时候,通常就是用于抗住并发量的,如果给 backend 过多的并发请求,很可能会占用后端过多的资源(比如线程、进程非事件驱动),最终反而会影响 backend 的处理能力。

阿里云 2 核 2G 服务器 3M 带宽 61 元 1 年,有高配

腾讯云新客低至 82 元 / 年,老客户 99 元 / 年

代金券:在阿里云专用满减优惠券

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2024-07-24发表,共计4628字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中

星哥玩云

星哥玩云
星哥玩云
分享互联网知识
用户数
4
文章数
19351
评论数
4
阅读量
7993246
文章搜索
热门文章
星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛 NAS-6:抖音视频同步工具,视频下载自动下载保存 前言 各位玩 NAS 的朋友好,我是星哥!...
星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛 NAS-3:安装飞牛 NAS 后的很有必要的操作 前言 如果你已经有了飞牛 NAS 系统,之前...
我把用了20年的360安全卫士卸载了

我把用了20年的360安全卫士卸载了

我把用了 20 年的 360 安全卫士卸载了 是的,正如标题你看到的。 原因 偷摸安装自家的软件 莫名其妙安装...
再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见 zabbix!轻量级自建服务器监控神器在 Linux 的完整部署指南 在日常运维中,服务器监控是绕不开的...
飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛 NAS 中安装 Navidrome 音乐文件中文标签乱码问题解决、安装 FntermX 终端 问题背景 ...
阿里云CDN
阿里云CDN-提高用户访问的响应速度和成功率
随机文章
还在找免费服务器?无广告免费主机,新手也能轻松上手!

还在找免费服务器?无广告免费主机,新手也能轻松上手!

还在找免费服务器?无广告免费主机,新手也能轻松上手! 前言 对于个人开发者、建站新手或是想搭建测试站点的从业者...
把小米云笔记搬回家:飞牛 NAS 一键部署,小米云笔记自动同步到本地

把小米云笔记搬回家:飞牛 NAS 一键部署,小米云笔记自动同步到本地

把小米云笔记搬回家:飞牛 NAS 一键部署,小米云笔记自动同步到本地 大家好,我是星哥,今天教大家在飞牛 NA...
12.2K Star 爆火!开源免费的 FileConverter:右键一键搞定音视频 / 图片 / 文档转换,告别多工具切换

12.2K Star 爆火!开源免费的 FileConverter:右键一键搞定音视频 / 图片 / 文档转换,告别多工具切换

12.2K Star 爆火!开源免费的 FileConverter:右键一键搞定音视频 / 图片 / 文档转换...
星哥带你玩飞牛 NAS-10:备份微信聊天记录、数据到你的NAS中!

星哥带你玩飞牛 NAS-10:备份微信聊天记录、数据到你的NAS中!

星哥带你玩飞牛 NAS-10:备份微信聊天记录、数据到你的 NAS 中! 大家对「数据安全感」的需求越来越高 ...
颠覆 AI 开发效率!开源工具一站式管控 30+大模型ApiKey,秘钥付费+负载均衡全搞定

颠覆 AI 开发效率!开源工具一站式管控 30+大模型ApiKey,秘钥付费+负载均衡全搞定

  颠覆 AI 开发效率!开源工具一站式管控 30+ 大模型 ApiKey,秘钥付费 + 负载均衡全...

免费图片视频管理工具让灵感库告别混乱

一言一句话
-「
手气不错
4盘位、4K输出、J3455、遥控,NAS硬件入门性价比之王

4盘位、4K输出、J3455、遥控,NAS硬件入门性价比之王

  4 盘位、4K 输出、J3455、遥控,NAS 硬件入门性价比之王 开篇 在 NAS 市场中,威...
12.2K Star 爆火!开源免费的 FileConverter:右键一键搞定音视频 / 图片 / 文档转换,告别多工具切换

12.2K Star 爆火!开源免费的 FileConverter:右键一键搞定音视频 / 图片 / 文档转换,告别多工具切换

12.2K Star 爆火!开源免费的 FileConverter:右键一键搞定音视频 / 图片 / 文档转换...
如何安装2026年最强个人助理ClawdBot、完整安装教程

如何安装2026年最强个人助理ClawdBot、完整安装教程

如何安装 2026 年最强个人助理 ClawdBot、完整安装教程 一、前言 学不完,根本学不完!近期,一款名...
星哥带你玩飞牛NAS-14:解锁公网自由!Lucky功能工具安装使用保姆级教程

星哥带你玩飞牛NAS-14:解锁公网自由!Lucky功能工具安装使用保姆级教程

星哥带你玩飞牛 NAS-14:解锁公网自由!Lucky 功能工具安装使用保姆级教程 作为 NAS 玩家,咱们最...
开发者福利:免费 .frii.site 子域名,一分钟申请即用

开发者福利:免费 .frii.site 子域名,一分钟申请即用

  开发者福利:免费 .frii.site 子域名,一分钟申请即用 前言 在学习 Web 开发、部署...