nginx分发算法

木木2年前技术文章624

一、分发算法介绍

如何将用户请求按照一定的规律分发给业务服务器。主要分为Nginx集群默认算法和基于请求头分发算法。

二、nginx集群默认算法

nginx的upstream 目前支持4种方式的分配

  • 轮询(默认) 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。用于处理静态页面

  • weight 指定权重,数值大的服务器,获得的请求的数量越多,用于后端服务器性能不均的情况。用于处理静态页面

  • ip_hash 每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务,好处是可以解决session的问题。可以处理动态网站。

  • url_hash(第三方) 按访问url的hash结果来分配请求,使每个url定向到同一个后端服务 ,后端服务器为缓存时比较有效。

nginx有很多第三方模块,各位可以去下载使用

https://www.nginx.com/resources/wiki/modules/

三、nginx业务服务器状态

每个设备的状态设置参数:

  • down 表示当前的server暂时不参与负载;

  • weight 默认为1,weight越大,负载的权重就越大;

  • max_fails 允许请求失败的次数默认为1,当超过最大次数时,返回proxy_next_upstream模块定义的错误;

  • fail_timeout 失败超时时间,在连接Server时,如果在超时时间之内超过max_fails指定的失败次数,会认为在fail_timeout时间内Server不可用,默认为10s

  • backup 其他所有的非backup机器down或者忙的时候,请求backup机器。所以这台机器压力会最轻。

四、nginx集群默认算法测试

实验环境

实验机 :四台虚拟机,一台测试机,一台分发器,两台web服务器。

网卡:vmnet4

系统:CentOS8.0

SELinux&防火墙:关闭

网段:192.168.0.0/24

image20200221112806031.png

实验拓扑

image20200220115749617.png

4.1、轮询算法

upstream web {
   server 192.168.0.42;
   server 192.168.0.43;
}
server {
   listen 80;
   server_name localhost;
   location / {
       proxy_pass http://web;
   }
}

前面已经测试验证了轮询算法分发。

配置backup参数

upstream web {
   server 192.168.0.42;
   server 192.168.0.43 backup;
}
server {
   listen 80;
   server_name localhost;
   location / {
       proxy_pass http://web;
   }
}

先正常访问测试

[root@client ~]# curl 192.168.0.40
web1
[root@client ~]# curl 192.168.0.40
web1
[root@client ~]# curl 192.168.0.40
web1

关停第一个节点情况,访问尝试:

[root@web1 ~]# systemctl stop httpd
[root@client ~]# curl 192.168.0.40
web2
[root@client ~]# curl 192.168.0.40
web2
[root@client ~]# curl 192.168.0.40
web2

启动第一个节点测试

[root@web1 ~]# systemctl start httpd
[root@client ~]# curl 192.168.0.40
web1
[root@client ~]# curl 192.168.0.40
web1
[root@client ~]# curl 192.168.0.40
web1

4.2、基于权重

通过配置权重,可以让性能好的服务器承担更多的负载

upstream web {
   # 设置权重比例1:2
   server 192.168.0.42 weight=1;
   server 192.168.0.43 weight=2;
}
server {
   listen 80;
   server_name localhost;
   location / {
       proxy_pass http://web;
   }
}

测试

[root@client ~]# curl 192.168.0.40 
   web1
[root@client ~]# curl 192.168.0.40
   web2
[root@client ~]# curl 192.168.0.40
   web2
[root@client ~]# curl 192.168.0.40
   web1
[root@client ~]# curl 192.168.0.40
   web2
[root@client ~]# curl 192.168.0.40
   web2

4.3、基于ip_hash分发

ip_hash算法能够保证来自同样源地址的请求都分发到同一台主机。   需要注意:ip_hash算法不支持backup、weight设置。默认权重为1。

upstream web { 
   ip_hash;    # 指定ip_hash即可,默认weight权重比例1: 1
   server 192.168.0.42;
   server 192.168.0.43;
}
server {
   listen 80;
   server_name localhost;
   location / {
       proxy_pass http://web;
   }
}

测试

[root@client ~]# curl 192.168.0.40
web2
[root@client ~]# curl 192.168.0.40
web2
[root@client ~]# curl 192.168.0.40
web2
切换到另外一台不同网段的主机
MacBook-Pro:~ hello$ ifconfig
vmnet8: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
ether 00:50:56:c0:00:08
inet 172.16.121.1 netmask 0xffffff00 broadcast 172.16.121.255

MacBook-Pro:~ hello$ curl 172.16.121.134
web1
MacBook-Pro:~ hello$ curl 172.16.121.134
web1
MacBook-Pro:~ hello$ curl 172.16.121.134
web1

4.4、基于url的hash

不同的URL我去找不同的机器访问,就是把url计算出一个值然后除以机器的数量取余 ,需要安装第三方插件

nginx分发器上,将nginx主程序包和下载好的第三方软件包放在同一个目录下解压
[root@master ~]# cd nginx-1.15.12/
[root@master ~]# ./configure --prefix=/usr/local/nginx --add-module=/root/ngx_http_consistent_hash-master
第三方模块的安装方法

[root@master ~]# make & make install
[root@master ~]#  vim /usr/local/nginx/conf/nginx.conf


worker_processes  1;
events {
   worker_connections  1024;
}
http {
   include       mime.types;
   default_type  application/octet-stream;
   sendfile        on;
   keepalive_timeout  65;
   upstream web {
       consistent_hash $request_uri;
       server 192.168.0.42 ;
       server 192.168.0.43 ;
   }
   server {
       listen       80;
       server_name  localhost;
       location / {
           proxy_pass http://web;
       }
       error_page   500 502 503 504  /50x.html;
       location = /50x.html {
           root   html;
       }
   }
}
[root@master ~]# /usr/local/nginx/sbin/nginx

在web主机上生成测试页面
[root@web1 ~]# for i in `seq 1 10`; do echo "web1_$i" > /var/www/html/$i.html; done

[root@web2 ~]# for i in `seq 1 10`; do echo "web2_$i" > /var/www/html/$i.html; done
这样我们就知道测试的时候访问的是哪台机器的页面文件了

测试访问
[root@client ~]# for i in `seq 1 10`; do curl http://192.168.0.40/$i.html; done
web1_1
web1_2
web1_3
web2_4
web2_5
web1_6
web2_7
web1_8
web2_9
web2_10

这个方式一般用在我们的缓存上,目的是为了命中率,什么是命中率,也就是说同样是下数据,你要是从源下就是没有命中,从缓存下就是命中


相关文章

SonarQube 代码质量平台

SonarQube 代码质量平台

官网:https://www.sonarqube.org/SonarQube 是一个开源的代码质量管理系统。可以对代码进行自动审查,检测代码中的错误、漏洞和代码味道。它可以与您现有的工作流程集成,以实...

Kafka 单条日志传输大小

kafka 对于消息体的大小默认为单条最大值是1M 但是在我们应用场景中, 常常会出现一条消息大于1M,如果不对kafka 进行配置。则会出现生产者无法将消息推送到kafka 或消费者无法去消费kaf...

sql_mode参数

sql_mode参数

一、参数含义sql_mode是个很容易被忽视的变量,其本身主要就是一种语法校验规则 ,默认值是空值,在这种设置下是可以允许一些非法操作的,比如允许一些非法数据的插入。二、常用值含义1、ONLY_FUL...

大数据集群部署规划(五)规划HDFS容量

        HDFS DataNode以Block的形式,保存用户的文件和目录,同时在NameNode中生成一个文件...

MySQL运维实战(5.1) 字符和编码的基本概念

MySQL运维实战(5.1) 字符和编码的基本概念

字符和编码字符字符是符号,是人们用于交流的各类符号,如26个英文字母、汉字、标点符号、数学运算符、其他语言的字母和符号。编码编码是计算机中以二进制方式存储字符的方式。字符集字符集是字符和编码的映射表。...

Linux高并发系统内核优化

1)timewait的数量,默认是180000。(Deven:因此如果想把timewait降下了就要把tcp_max_tw_buckets值减小)net.ipv4.tcp_max_tw_buckets...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。