nginx在做负载均衡时如何配置
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了nginx在做负载均衡时如何配置相关的知识,希望对你有一定的参考价值。
参考技术A 1、下面的架构就是我们今天的演示结构,后端有两台服务器,分别是node1和node2,前端是一台web服务器,然后在web服务器上做负载均衡,将前端的访问流量导到后端的两个节点服务器上。三个服务器的IP地址分别是:web:192.168.1.210node1:192.168.1.211node2:192.168.1.2122、按照这样的架构,在后端的node1和node2节点上分配配置好需要访问的网站,然后为了方便测试,我们将两个网站的主页分别改成下面的内容。便于区分访问的节点。
3、后端两个节点配置好以后,我们再来配置web服务器里的负载均衡配置,首先使用默认配置,先打开/etc/nginx/nginx.conf配置文件,在http区块里添加upstream块内容,及配置了两个后端服务器,后端负载均衡集群的名称是backend,记下这个名称。
4、然后再打开/etc/nginx/conf.d/default.conf这个配置文件,在server区块里,把location里面的内容改成图中所示内容。即将所有访问192.168.1.210的流量代理到后端的backend集群里。
5、配置文件配置好以后,使用nginx-t命令测试一下配置文件,保证配置文件是ok状态,然后执行nginx命令启动nginx服务器。
6、启动后在浏览器上输入前端web服务器的ip地址192.168.1.210,然后可以看到第一次是node1响应的,然后刷新一下以后,又变成了node2响应的。就这样实现了负载均衡的效果。由两个服务器分别响应,是因为默认的负载均衡算法是轮询算法,即两个节点轮流来。
7、然后我们还可以尝试一下加权轮询算法,即给不同的节点配置不同的权重,权重高一点的服务器,响应的多一些,权重第一点的响应少一些。加权轮询算法配置,在后端服务器后面加上权重值weight即可。配置好以后,执行nginx-t命令检测配置文件,确认无误后,执行nginx-sreload命令重新加载配置文件。
8、通过加权轮询的方式,我们无法通过手动一次次点击,最后来统计次数。但是我们可以使用自动化工具来统计。使用的工具是一款叫做httpd-tools的软件,安装好以后,提供了一个ab命令
9、然后我们来执行ab命令进行测试,常用的格式是:ab-n1000-c50http://localhost这个命令是在210服务器上执行的。表示一共执行1000次访问,每次发送50个请求。
10、然后我们登录到后端的node1服务器上,打开nginx的访问日志,从中可以看到ab命令测试的访问信息里,访问来源都是ApacheBench,因此可以通过可以来源来统计nginx响应的次数。命令是:grepApacheBenchaccess.log|wcnode1和node2节点上的统计结果分别是714和286,如下面图中所示,虽然没有达到5:2的权重比例,但是也非常接近了。说明这个配置生效了。
负载均衡 之 nginx+consul+consul template
前几篇先是记载了如何通过nginx配置服务负载均衡,后面记载了如何通过 ocelot 配置 服务负载均衡,分别介绍了用webapi注册服务以及配置文件注册服务,通过ocelot webapi + consul 配置负载均衡系列学习完毕。
然而nginx负载均衡没有服务发现,依然不能用生产环境,本篇将介绍如何通过 nginx+consul 配置多台服务器的负载均衡并支持服务发现。
试验背景和目的:一个微服务,有一个网关入口,如果网关出现故障,那么整个微服务马上瘫痪,那么我们有必要把网关布署在多台服务器上,如果其中有一台出现故障,还有其他服务器在起到微服务网关角色。
下面依然是在同一台linux机子上模似和试验。
内容包括:
1. nginx服务,做负载均衡
2. consul服务,做服务发现
3. consul template,做动态改变nginx配置并重启nginx服务
4. 3个网关webapi,分别是
192.168.1.23:8101
192.168.1.23:8102
192.168.1.23:8103
(在展开试验步骤之前,对背景进行大概的介绍是非常重要,我发现很多技术文章一上来二话不说就是贴代码)
$ wget https://releases.hashicorp.com/consul/1.4.4/consul_1.4.4_linux_amd64.zip
$ sudo apt-get install unzip
$ unzip consul_1.4.4_linux_amd64.zip
$ sudo mv consul /usr/local/bin/consul
以上命令,在官网下了个包,然后解压了一下,里面只有一个 consul文件,把文件移到了/usr/local/bin/consul。
{
"encrypt": "Wd7HAMtcgg5RQ2hZhHE9xw==",
"services": [
{
"id": "api1",
"name": "apigateway",
"tags": [ "apigateway" ],
"address": "192.168.1.23",
"port": 8101,
"checks": [
{
"id": "ApiServiceA_Check",
"name": "ApiServiceA_Check",
"http": "http://192.168.1.23:8101/health",
"interval": "10s",
"tls_skip_verify": false,
"method": "GET",
"timeout": "1s"
}
]
},
{
"id": "api2",
"name": "apigateway",
"tags": [ "apigateway" ],
"address": "192.168.1.23",
"port": 8102,
"checks": [
{
"id": "ApiServiceB_Check",
"name": "ApiServiceB_Check",
"http": "http://192.168.1.23:8102/health",
"interval": "10s",
"tls_skip_verify": false,
"method": "GET",
"timeout": "1s"
}
]
}
]
}
3、安装 consul-template,
$ wget https://releases.hashicorp.com/consul-template/0.19.3/consul-template_0.19.3_linux_amd64.zip $ unzip consul-template_0.19.3_linux_amd64.zip $ mv consul-template /usr/bin/
测试一下安装有没有成功:
$ consul-template -v
4、创建一个consul 模板文件
文件内容:
upstream ocelot { {{range service "apigateway"}} server {{ .Address }}:{{ .Port }}; {{ end }} } server { listen 8105; location / { proxy_pass http://ocelot ; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection keep-alive; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_cache_bypass $http_upgrade; } }
相比之前写死下游服务节点:
upstream ocelot { server localhost:8104; server localhost:8102; server localhost:8103; }
现在这块的内容,将会动态地去consul服务数据库中读取,注意服务名称,"apigateway", 这个名称是注册到consul时所用的 service name。
模板准备好之后,要被nginx配置所引用,下面修改nginx的配置文件:
include /consul/nginx-template/*.conf;
加上这一句,意思是 引用一下
/consul/nginx-template/ 下面的所有conf文件的nginx配置信息
下面运行consul-template:
consul-template --consul-addr 192.168.1.23:8500 --template "/consul/nginx-template/nginx.ctmpl:/consul/nginx-template/vhost.conf:service nginx restart" --log-level=info
这句的意思是,将从consul服务数据中读取 最新的服务发现结果,将有关于 apigateway 的数据,实时地更新到 consul/nginx-template/vhost.conf, 更新的过程用的模板是 /consul/nginx-template/nginx.ctmpl, 更新完之后顺便执行了一下 service nginx restart,重启了nginx服务。
执行完之后,我们可以看到 在consul/nginx-template/ 多了一个 vhost.conf文件,里面的内容是
upstream ocelot { server 192.168.1.23:8101; server 192.168.1.23:8102; server 192.168.1.23:8103; } server { listen 8105; location / { proxy_pass http://ocelot ; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection keep-alive; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_cache_bypass $http_upgrade; } }
确实是我们要内容。
下面,把其中一个webapi停掉,
$ supervisorctl $ stop apigateway3
把第3个网关api停掉了
看会发生什么事?
2019/04/17 07:59:24.954777 [INFO] (runner) initiating run 2019/04/17 07:59:24.958652 [INFO] (runner) rendered "/consul/nginx-template/nginx.ctmpl" => "/consul/nginx-template/vhost.conf" 2019/04/17 07:59:24.958722 [INFO] (runner) executing command "service nginx restart" from "/consul/nginx-template/nginx.ctmpl" => "/consul/nginx-template/vhost.conf" 2019/04/17 07:59:24.958913 [INFO] (child) spawning: service nginx restart
这时consul-template会告诉我们,nginx配置更新的消息,
再打开vhost.conf
upstream ocelot { server 192.168.1.23:8101; server 192.168.1.23:8102; } server { listen 8105; location / { proxy_pass http://ocelot ; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection keep-alive; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_cache_bypass $http_upgrade; } }
下游服务节点少了一个,nginx配置确实得到及时的更正。
将consul服务开启加入守护进程,以保证机器重启能自启动consul 服务:
[program:consul] command=consul agent -server -ui -bootstrap-expect=1 -data-dir=/tmp/consul -node=consul-1 -client=0.0.0.0 -bind=0.0.0.0 -datacenter=dc1 -config-dir=/consul/testservices startsecs=10 autostart=true autorestart=true stderr_logfile=/var/log/applogs/consul.err.log stdout_logfile=/var/log/applogs/consul.out.log user=root stopsignal=INT [program:consultemplate] command=consul-template --consul-addr 192.168.1.23:8500 --template "/consul/nginx-template/nginx.ctmpl:/consul/nginx-template/vhost.conf:service nginx restart" --log-level=info startsecs=10 autostart=true autorestart=true stderr_logfile=/var/log/applogs/consul-template.err.log stdout_logfile=/var/log/applogs/consul-template.out.log user=root stopsignal=INT
上面是在做试验,但生产环境下:
1.只有一台nginx服务器是不够的,最好要有两台nginx服务,通过keepalived配置两台nginx服务器,一主一从。这样就避免了如果一台nginx服务器故障了,就没法做负载均衡。
2.只有一个consul服务是不够的,官方建议是要有3个node共同组成一个datacenter。这样就避免了只有一台服务器在提供服务发现的功能。
3. 3个网关应该是部署在3台不同的web 服务器上面。
后面,可能会学习一下如果对2台nginx服务器做keepalive联盟。关于nginx+keepalive 配置双机 master/backup 的文章:https://blog.51cto.com/12922638/2155817
本文参考文章:https://www.jianshu.com/p/fa41434d444a
最后盗一下里面两张图:
以上是关于nginx在做负载均衡时如何配置的主要内容,如果未能解决你的问题,请参考以下文章