【实战】5 分钟学会 Nginx 负载均衡
陆阳阳,微医前端技术部前端开发工程师,做一条安静的咸鱼。
前言
这篇文章需要一点点的 nginx 基础知识~
不会也没关系,先给各位贴一个最简单的 nginx.conf
配置,看完就会
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 8081;
server_name localhost;
location / {
proxy_pass http://0.0.0.0:9000;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
并且起一个最简单的 node 服务:
const http = require('http');
const server = http.createServer();
const host = '0.0.0.0'
const port = 9000
let n = 0
server.on('request', function (req, res) {
n += 1
console.log('请求来了: ', n)
res.write('Hello World!!!');
res.end();
});
server.listen(port, host, function () {
console.log(`服务器启动了,请访问:http://${host}:${port}`);
})
访问 http://localhost:8081/
, nginx
已经能把请求正常打到 node 9000
端口的服务了
接下来进入正题,讲讲负载均衡了~
什么是负载均衡
举个例子,工地上新到了一车砖,老板要求天黑之前需要搬完。但是工地上只有一个工人,这种情况下每趟要搬 1000 斤才有可能在天黑前搬完。但是如果 1000 斤的砖扛在肩上,那这个工人一下就被打死了。这个时候包工头另外招了两个人,三个人一起干,每个人扛 300 斤,那大家都很轻松的把活干完了,没人会死。
放到服务器上也是同样的道理。现在假设每秒钟有 1000 个请求,一台服务器处理不过来,分分钟会挂掉。我们把服务器加到 3 台,这样每台处理 300 个,每台都轻轻松松。
那么问题来了,三个工人的身体强弱是有区别的。包工头在安排活的时候是做到绝对的公平每人背 300 斤?还是按照实工人实际身体情况,能者多劳?
服务器也是一样的道理,不同的服务器处理能力是不一样的。nginx 负载均衡
做的事情就是根据服务器的能力去 平衡
大量请求到达各个服务器的数量。这里的 平衡
并不是绝对的 平均
,具体怎么样去平衡请求,我们可以根据自己的需求去设置不同的 平衡策略
负载均衡策略
轮询策略(默认)
按照上面讲的,要玩负载均衡,首先得是多台机器,一台也玩不起来啊。但是条件有限,我这边在不同端口起多个相同的 node 服务来表示多台机器:
如上图,三个服务完全相同,分别用 9000
、9001
、9002
端口启动,接下来修改 nginx.conf
文件,nginx 负载均衡
主要是通过配置 upstream
来实现的:
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
upstream test {
server 0.0.0.0:9000;
server 0.0.0.0:9001;
server 0.0.0.0:9002;
}
server {
listen 8081;
server_name localhost;
location / {
proxy_pass http://test;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
从上面代码可以看出,改动是比较简单的,增加了一个 upsteam
配置。这个是最简单的 轮询策略
,大量请求打过来后,nginx
将这些请求 平均
分配到 3 台服务器上。接下来我们通过工具批量发送 600 个请求, 来测试下我们的配置是否生效:
从结果来看符合预期, 每个服务处理 200 个请求。
加权轮询策略
这个也很简单,从名字可以猜出来一些,这个是按照我们指定的权重来轮询,nginx.conf
修改如下:
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
upstream test {
server 0.0.0.0:9000 weight=2;
server 0.0.0.0:9001 weight=1;
server 0.0.0.0:9002 weight=1;
}
server {
listen 8081;
server_name localhost;
location / {
proxy_pass http://test;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
再来测试下,批量发送 100 个请求看看结果:
符合预期
ip_hash 策略
这个也很简单,看名字也能猜出来一点,根据 ip 来分配请求。固定的客户端发出的请求会被固定分配到一台服务器。接着修改 nginx.conf
配置
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
upstream test {
ip_hash;
server 0.0.0.0:9000;
server 0.0.0.0:9001;
server 0.0.0.0:9002;
}
server {
listen 8081;
server_name localhost;
location / {
proxy_pass http://test;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {w
root html;
}
}
}
这里还是因为条件不允许,照理要用多个客户端来访问,并在控制台打出 ip 来看结果,但是我只有本机一台机器,所以做不了这个实验。
用迂回一点的方式来验证下,既然是根据 ip 来分配请求的,那我本机发 100 个请求,这 100 个请求应该会被打到同一台服务器上,另外两台接收到的请求数量为 0,来测试下:
从结果来看也是符合预期的,这里只有 9002 端口起的服务收到了 100 个请求,其他两个服务收到的请求数量为 0
总结
虽然短小了点,但是花5分钟应该能完全看懂 nginx 负载均衡
了,以后再也不怕别人装逼了~