本文介绍了Nginx的负载均衡策略,一致性hash分配原理,及常用的故障节点的摘除与恢复配置。

文章来源:宜信技术学院 & 宜信支付结算团队技术分享第一期-宜信支付结算八方数据团队高级技术经理 周恒《Nginx的细枝末节》

分享者:宜信支付结算八方数据团队高级技术经理 周恒

原文首发于支付结算技术团队公号:野指针

前篇Nginx专题(1):Nginx之反向代理及配置详细介绍了Nginx功能之一——反向代理。本篇文章将重点介绍Nginx功能之二——负载均衡。

为了增加对负载均衡的好感,我们先了解负载均衡能实现什么。

  • 将多个服务器节点绑定在一起提供统一的服务入口。
  • 故障转移,在意外发生的时候,可以增加一层保险,减少损失。
  • 降低上线运维复杂度,实现平滑上线。运维和开发同学都喜欢。

下面正式进入主题。

一、Nginx的负载均衡策略

负载均衡就是将请求“均衡”地分配到多台业务节点服务器上。这里的“均衡”是依据实际场景和业务需要而定的。

对于Nginx来说,请求到达Nginx,Nginx作为反向代理服务器,有绝对的决策权,可以按照规则将请求分配给它知道的节点中的一个,通过这种分配,使得所有节点需要处理的请求量处于相对平均的状态,从而实现负载均衡。

Nginx支持的负载均衡策略很多,比较重点的如下:

  • round robin(轮询)
  • random(随机)
  • weight(权重)
  • fair(按响应时长,三方插件)
  • url_hash(url的hash值)
  • ip_hash(ip的hash值)
  • least_conn(最少连接数)

这么多的策略,非常不利于记忆和选择,我们不妨将这些常见的策略归类,分而化之,方便挑选。

第一类 最佳实现

  • weight(权重)
  • random(随机)

最佳实践,其实就是最常见、最普通的默认配置,当然也是在一定程度上最好用的配置。不知道用什么方式的时候,就可以选择用这一类型。

轮询不用多说。这里的随机,其实在大量请求的情况下,按照概率的理论等同于轮询的方式。

轮询配置参考:

#默认配置就是轮询策略
upstream server_group {
server backend1.example.com;
server backend2.example.com;
}

随机配置参考:

upstream server_group {
random;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
server backend4.example.com;
}

第二类 性能优先

  • weight(权重)
  • fair(按响应时长,三方插件)
  • least_conn(最少连接数)

让业务节点中性能更强的机器得到更多请求,这也是一个比较好的分配策略。

什么是性能更好的机器?这个问题也有很多的维度去考量。

  • 从经验或硬件上分为高权重、低权重的机器。
  • 按照节点请求的响应时长来决定是多分配请求,还是少分配请求。
  • 按照保持的连接数。一般来说保持的连接数越多说明处理的任务越多,也是最繁忙的,可以将请求分配给其他机器处理。

权重的配置参考:

upstream server_group {
server backend1.example.com weight=;
#默认为不配置权重为1
server backend2.example.com;
}

响应的时长(fair)配置参考:需要在Nginx编译时加入nginx-upstream-fair模块。

upstream server_group{
fair;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
server backend4.example.com;
}

最少连接数(least_conn)配置参考:

upstream server_group {
least_conn;
server backend1.example.com;
server backend2.example.com;
}

第三类 保持稳定

  • ip_hash
  • url_hash

很多请求都是有状态的,上一次请求到哪个业务节点,这次还要请求到哪台机器。比如常见的session就是这样一种有状态的业务。

这里Nginx提供了按照客户端ip的hash来作为用户的标示分配、url的hash作为分配标示的规则。本质上还是要找到用户的请求中不变的要素,抽离出来,这样就可以进行分配了。

ip_hash配置参考:

upstream server_group {
ip_hash;
server backend1.example.com;
server backend2.example.com;
}

url_hash配置参考:

upstream server_group{
hash $request_uri consistent;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
server backend4.example.com;
}

二、Nginx支持一致性哈希进行分配

Nginx支持一致性hash进行分配,也就是配置中consistent。

什么是一致性hash?为什么要引入这个机制?在生产环境下,业务节点经常会出现增加或减少的情况,就算这种增加或减少都是被动的,也可能会对hash分配产生影响。如何能够做到尽量减少影响呢?这时一致性hash被发明出来。

一致性hash解决两个问题:

  • 分配特别不均匀;
  • 节点变动除了对分配到这个节点上的请求有影响,还会导致其他节点上的请求重新分配。

1)如何解决分配不均的问题

将原来的每一个节点复制出N个虚拟节点,并且给这些虚拟节点都起个名字。

比如原来有5个节点,分配的时候经常会不均匀,现在每个节点都虚拟出N个节点,就是5*N个节点,会极大降低分配不均匀的情况。下面就要说说如何分配的问题了。

2)如何解决节点变动的问题

一致性哈希的基本思想:

  • 定义一个[0,(2^32)-1]的数值空间。相当于取长度从 0到2^32-1 的线段。
  • 节点映射到线段上。将每个节点,包括虚拟节点,都通过hash算法得到数值,然后映射到这个取值区间上。

如下图。

  • 计算数据的Hash值。把请求中的关键字符串通过hash算法得到一个数值,在线段中找到一个位置,如果算出来的数值大于2^32-1则认为是0。按照这个规则,其实是把这个线段首尾相连形成一个环,所以也叫hash环。
  • 数据节点在线段上找归属的节点。沿着这个线段向右找到离得最近的节点,并把该节点作为这个数据的归属节点。

下面再来看节点的变化对一致性Hash的影响。

  • 节点减少:比如NodeA突然故障了,原来分配到其他节点上的数据不会发生变化,只有分配到NodeA上的数据会重新找离它们最近的点,从而减少了hash重新分配的数量。这也是一致性hash最大的优势。
  • 节点增加:比如现在请求量抖增,需要增加节点降低负载。当新加入节点NodeE时,NodeE及它的一群虚拟节点会根据hash值分配在hash环上。这时,大部分数据再根据一致性哈希规则找其归属的Node节点都不会发生变化,只有那些值计算出来发现离NodeE更近的数据发生了变化,但数量毕竟是有限的,减少了因为节点增加造成的影响。

三、故障节点摘除与恢复

先看看经典配置,再详细解释。

upstream server_group {
server backend1.example.com ;
server backend2.example.com max_fails= fail_timeout=30s;
server backup1.example.com backup;
}

max_fails=number

这个参数决定了多少次请求后端失败后会暂停这个业务节点,不再给它发新的请求,默认值是1。此参数需要配合fail_timeout一起用。

题外话:如何定义失败,有很多种类型,这里因为主要处理HTTP代理,所以更关注proxy_next_upstream。

proxy_next_upstream:主要定义了当服务节点出现状况时,会将请求发给其他节点,也就是定义了怎么算作业务节点失败。

fail_timeout=time

决定了当Nginx认定这个节点不可用时,暂停多久。不配置默认就是10s。

把上面两个参数联合起来考虑就是:当Nginx发现发送到这个节点上的请求失败了3次的时候,就会把这个节点摘除,摘除时间是30s,30s后才会再次发送请求到这个节点上。

backup

类似于switch语句中的default,当主要节点都挂了的时候,会把请求打到这个backup节点。这是最后一个救兵了。

四、总结

由于Nginx采用了反向代理技术,对于请求的转发有绝对的控制权,使得负载均衡变成了可能。

本文介绍了负载均衡的概念,详细分类了Nginx的负载均衡策略,并提供了简单配置参考。同时介绍了一致性hash的原理,及常用的故障节点的摘除与恢复。下一篇将会介绍Nginx功能之三——HTTP缓存,敬请期待。

Nginx专题(2):Nginx的负载均衡策略及其配置的更多相关文章

  1. nginx负载均衡策略url_hash配置方法

    参考文章: https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/ 根据路径,进行一致性hash,具体的配 ...

  2. Nginx多种负载均衡策略搭建

    背景介绍 上篇介绍了利用Nginx反向代理实现负载均衡,本文详细讲述Nginx下的几种负载均衡策略. 轮询 轮询,顾名思义,就是轮流请求,基于上篇文章的介绍,我们将负载均衡策略聚焦于default.c ...

  3. nginx的6种负载均衡策略

    在服务器集群中,Nginx起到一个反向代理服务器的作用.为了避免单独一个服务器压力过大导致服务器奔溃,就需要将不同用户的请求转发给不同给不同的服务器,保证集群中的每一台服务器都能正常运作,这种机制就叫 ...

  4. octavia的实现与分析(一)·openstack负载均衡的现状与发展以及lvs,Nginx,Haproxy三种负载均衡机制的基本架构和对比

    [负载均衡] 大量用户发起请求的情况下,服务器负载过高,导致部分请求无法被响应或者及时响应. 负载均衡根据一定的算法将请求分发到不同的后端,保证所有的请求都可以被正常的下发并返回. [主流实现-LVS ...

  5. openstack octavia的实现与分析(一)openstack负载均衡的现状与发展以及lvs,Nginx,Haproxy三种负载均衡机制的基本架构和对比

    [负载均衡] 大量用户发起请求的情况下,服务器负载过高,导致部分请求无法被响应或者及时响应. 负载均衡根据一定的算法将请求分发到不同的后端,保证所有的请求都可以被正常的下发并返回. [主流实现-LVS ...

  6. Dubbo的负载均衡策略&容错策略

    dubbo的负载均衡策略 RandomLoadBalance 随机调用负载均衡 默认方式该类实现了抽象的AbstractLoadBalance接口,重写了doSelect方法,看方法的细节就是首先遍历 ...

  7. nginx 负载均衡策略

    nginx 负载均衡策略   1. 轮询轮询方式是nginx负载均衡的默认策略,根据每个server的权重值来轮流发送请求,例如:upstream backend {server backend1.e ...

  8. nginx+tomcat负载均衡策略

    測试环境均为本地,測试软件为: nginx-1.6.0,apache-tomcat-7.0.42-1.apache-tomcat-7.0.42-2.apache-tomcat-7.0.42-3 利用n ...

  9. Nginx服务器之负载均衡策略(6种)

    一.关于Nginx的负载均衡 在服务器集群中,Nginx起到一个代理服务器的角色(即反向代理),为了避免单独一个服务器压力过大,将来自用户的请求转发给不同的服务器.详情请查看我的另一篇博客. 二.Ng ...

随机推荐

  1. vue proxyTable代理 解决开发环境的跨域问题

    如果我们项目请求的地址为 htttp://xxxx.com/a/b/c 可以设置代理为: dev:{ assetsSubDirectory: 'static',// 静态资源文件夹 assetsPub ...

  2. Anaconda的安装和详细介绍(带图文)

    Anacond的介绍 Anaconda指的是一个开源的Python发行版本,其包含了conda.Python等180多个科学包及其依赖项. 因为包含了大量的科学包,Anaconda 的下载文件比较大( ...

  3. Golang stackError 补充go错误定位能力

    用过go的都知道,go的error实现很简单,errors.New实现的error类并不存储堆栈数据,这导致一个问题,就是多次error return后,或panic后recover了,找不到触发异常 ...

  4. Thinkphp5与QueryList,也可以实现采集(爬虫)页面功能

    QueryList 是什么 QueryList是一套用于内容采集的PHP工具,它使用更加现代化的开发思想,语法简洁.优雅,可扩展性强.相比传统的使用晦涩的正则表达式来做采集,QueryList使用了更 ...

  5. MD5 加盐加密

    一.概述 MD5(Message Digest  Algorithm 5),是一种散列算法,是不可逆的,即通过md5加密之后没办法得到原文,没有解密算法. 在一般的项目中都会有登录注册功能,最简单的, ...

  6. spark集群搭建(三台虚拟机)——zookeeper集群搭建(3)

    !!!该系列使用三台虚拟机搭建一个完整的spark集群,集群环境如下: virtualBox5.2.Ubuntu14.04.securecrt7.3.6_x64英文版(连接虚拟机) jdk1.7.0. ...

  7. bash6——循环

    for fruit in apple orange pear #写死 do each ${fruit}s done fruits="apple orange pear" #输入变量 ...

  8. 开始逆向objc基础准备(二)我的平台是simulator-x86_64

    建项目运行中断调试,lldb中显示寄存器看到有rax-r15, stm0-stm7, xmm0-xmm15, ymm0-ymm15,即为x64体系支持sse4. 再在lldb中查看寄存器别名得到以下对 ...

  9. ansible on aws linux 2

    1. 安装epel yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm 2. 安 ...

  10. 物联网架构成长之路(47)-利用GitLab实现CI持续集成

    0.前言 前段时间,考虑到要练习部署一套CI/CD的系统.一开始考虑到Jenkins,随着这两天的了解,发现最新版的GitLab已经提供有CI/CD集成了.所以本次博客,干脆一步到位,直接用GitLa ...