Nginx 实现简易负载均衡
什么是负载均衡?
负载均衡(load balancing)可以直接拆解开来理解,把当前服务器的负载(主要指客户端请求)平衡分摊到其他服务器,从而达到增加当前服务器吞吐量,提升请求性能, 提高容灾的目的。
可以用平台订单的分拨做类比。比如说一个淘宝商家本来是自营的,自己卖的的东西自己生产,生产好了之后,再从当地发货到全国。现在生意做打了,订单量多到工厂产能不足,且因为产品具有一定的时效性,快递运送时间太长客户就不愿意买了。这时候就需要根据平台的订单收货地做一个排名,排名在前的城市优先建立新的工厂和生产线,优先供给。然后将新建工厂的城市辐射区域的订单分拨到新厂生产。
这时候产能上来了,订单反倒不足了。是关闭工厂节约成本,还是扩大订单量呢?市场一片大好,当然是要扩大订单量。商户自己做这事,品牌推广有点慢,就开始招全国各地代理商。甚至会给零散个体户做一件代发服务(本地工厂,闲着也是闲着)。
这是一个沙漏模型,一边是客户和代理商,一边是商家和工厂。负载均衡做的就是类似商家跟工厂端的优化升级,当前服务器负载压力大,就把当前服务器作为一个代理服务器,将用户请求分发到其他的服务器,这个概念叫反向代理。点我查看正向代理与反向代理
Nginx 实现负载均衡的几种方式
Nginx 使用 upstream 定义虚拟服务池,就是请求可转发的服务器列表。一般为 IP 地址,可以加如 :80
的端口号。使用域名会自动将其转化为域名映射所在 IP 地址,然后转发请求(自己测试过,以为添加多个虚拟主机就可以访问实现这个负载均衡的概念,结果都指向到 IP 地址,也是服务器默认的虚拟主机地址)。
...
upstream backend_server {
server 192.168.1.13;
server 192.168.1.14;
}
server {
...
- 轮询(默认)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器 down 掉,会自动跳过,当后端服务器再次响应时,会自动恢复。
- 权重(weight)
给虚拟服务池中的每个服务器添加 weight 属性(默认为 1),然后按照权重分配访问比率。
upstream backend_server {
server 192.168.1.13:9001 weight=1;
server 192.168.1.14:9002 weight=2;
}
- ip_hash
根据请求 ip 地址(包含端口号) hash 值分配。主要解决登录状态(即 Session)保持的问题。开启后,如果客户已经访问了某个服务器,当再次访问时,会将请求通过哈希算法,自动定位到该服务器。
upstream backend_server {
ip_hash;
server 192.168.1.13:9001;
server 192.168.1.14:9002;
}
- fair
第三方 Nginx 模块,需要下载跟 Nginx 一起编译安装,用 nginx -V
查看当前版本是否已安装。直接使用,会报错,指令无法识别。
安装教程:已经安装Nginx的基础上增加新模块(例子nginx-upstream-fair)
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
upstream backend_server {
fair;
server 192.168.1.13:9001;
server 192.168.1.14:9002;
}
- url_hash
按访问 url 的 hash 结果来分配请求,使每个 url 定向到同一个后端服务器,后端服务器为缓存时比较有效。主要应用在请求第三方资源上,服务器群会缓存这样的资源,然后返回给用户。但每个服务器都去缓存一遍相同的资源太浪费带宽和存储空间了,用 url_hash 可以将同一资源请求规整到同一个服务器上,增加命中率。
upstream backend_server {
server 192.168.1.13:9001;
server 192.168.1.14:9002;
hash $request_uri;
hash_method crc32;
}
每个服务器的状态设置:
down
表示单前的server
暂时不参与负载weight
默认为 1。weight
越大,负载的权重就越大。max_fails
允许请求失败的次数,默认为 1。当超过最大次数时,返回proxy_next_upstream
模块定义的错误fail_timeout
max_fails
次失败后,暂停的时间。backup
其它所有的非backup
机器down
或者忙的时候,请求backup
机器。所以这台机器压力会最轻。
完整的简易负载均衡方案
修改 nginx.conf
文件
...
# 一般会建议与代理服务器核心数一致
worker_processes 4;
events {
# 最大并发数
worker_connections 1024;
}
http{
# 待选服务器列表
upstream backend_server {
# ip_hash指令,将同一用户引入同一服务器。
ip_hash;
server 192.168.1.13:9001;
server 192.168.1.14:9002;
}
server{
# 监听端口
listen 80;
server_name lb.seasidecrab.com;
#root /usr/local/nginx/html;
#index index.html index.htm index.php;
# 根目录下
location / {
# 选择哪个服务器列表
proxy_pass http://backend_server;
proxy_set_header host $host;
}
}
}
查看 CPU 个数和核心数指令
查看 CPU 个数
cat /proc/cpuinfo | grep 'physical id' | sort | uniq | wc -l
查看 CPU 核数
cat /proc/cpuinfo | grep 'process' | sort | uniq | wc -l
PS:这个方法相当于查看系统文件里的描述,对于升级过的系统没有更新信息,所以可能不准确。
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。