最近需要给一个现网server增加过载保护的功能,借此机会也思考了很多,简单谈谈我对这两个概念的理解和实现方法。
一.负载均衡
简单来说,就是按照目标server的参数进行合理分配,这个参数可以是失败率,也可以是响应时间,也可以是请求量,甚至是随机数。
我们来按照从简单到复杂逐个看一下几种实现。
1.轮询式
逻辑比较简单,直接看代码:

如上代码就是一个简单的轮询式分配方法,这种方法优点实现简单,cpu计算少,缺点就是无法动态判断server的状态,当后端有一台server挂掉的时候,会至少1/vecServer.size()的请求。(最为严重的情况是由于单台后端server的超时导致前段全部挂死)。而且这种分配方法有一个bug,就是当每次请求结束后就释放内存,那么curIndex永远都只会为0,即每次都请求第一个server。

2.定死权重式
这种方式适用于那种需要实现就规定后端server的权重,比如A比Bserver的响应速度快,我们希望A接受的请求比B多。

上面的代码也比较好理解,一共有两个数组,一个是server信息数组vecServer,一个是权重数组vecWeight。在分配server时,先通过权重数组vecWeight获取到server信息数组的下标,然后分配server。
这样的做法在我1年半写的一个项目是有使用的,经过统计效果是很不错的,基本是访问量是严格按照权重比分配的。这样做的cpu消耗也不高,但是缺点也是显而易见的,就是还是没有办法动态调整权重,需要人为去修改。所以我们接下来看第三种。

3.动态调整权重
要讨论这种方法前,我们先要明确几个希望使用他的原因:

然后是我们实现方法,很明显,我们需要一个基准来告诉我们这台server是否是正常的。这个基准是什么,是历史累计的平均值。比如如果是按照响应时间分配权重,那么就是所有后端server历史累计的平均响应时间,如果是错误率也是如此。
那么一旦调整了权重,我们什么时候来调整权重呢,调整比例是怎样呢?按照我的经验,一般是隔一段固定时间才进行调整,如果正常但是权重过低,那么就按照20%的比例恢复;如果server不正常,那么直接按照当前server响应时间/历史平均响应时间进行降权。这里的逻辑之所以不一样是有原因的,因为服务出现问题的时候,我们是能够知道这坏的程度有多少的,就是当前server响应时间/历史平均响应时间进行降权;但是要恢复的时候,你并不能保证server能够支撑到多大的访问量,所以只能按照20%放量来试。也避免滚雪球效应的发生。
我们来看一下代码。

以上基本展示了动态调整的过程,代码可能只是起演示作用,很多比如越界的检测都没有做,大家参照就好~

OK,到这里我们基本就结束了负载均衡的讨论了,但是还有一个话题:过载保护。
二.过载保护
关于过载保护其实经常适合负载均衡结合在一起使用的,但有两个问题:

代码如下:

上面的代码为了演示方便,所以把两个for循环拆开了,实际上是应该合到一个里面写的。
OK,就是这样,大家如果有不同的想法欢迎提出。

bayonet开源网络服务器框架正式完成!

博客这几天由于服务器的问题打不开,在这里跟大家抱歉啦 老读者应该都知道,笔者有两个开源项目,分别是: fuload: 性能测试工具,可以用来给服务器做压力测试...

阅读全文

有限状态机的C++实现(2)-bayonet开源网络服务器框架

接着上一篇文章: 有限状态机的C++实现(1)-epoll状态机,我们今天来介绍更复杂和深入的部分。 为什么会在标题中提到bayonet这个开源项目呢?笔者本人一直想要...

阅读全文

8则回应给“关于负载均衡和过载保护的一些想法和实现”

  1. hwywhywl说道:

    博主帮忙看看
    “————-.vimrc reload setting——–
    let mapleader = ‘,’

    nmap ss :source ~/.vimrc

    nmap ee :ee ~/.vimrc

    autocmd! bufwritepost .vimrc source ~/.vimrc
    这几句 执行 ,ss ,ee
    vim 提示 E492: Not an editor command: ,ss

    [回复]

    Dante 回复:

    呃,你这是映射了
    ee 这个命令。。。
    不是,ee

    [回复]

    hwywhywl 回复:

    都不行 ee 也还是出现类似得错误

    [回复]

    Dante 回复:

    nmap ee :ee ~/.vimrc
    这句你是想写:
    nmap ee :e ~/.vimrc
    吧?
    手误?

    [回复]

    hwywhywl 回复:

    解决了!首先是一开始不大明白这句命令得语法,接着是手误。现在还不明白 nmap 与 map 有什么区别?

    [回复]

    Dante 回复:

    nmap是normal模式下的映射。
    而map在normal,virtual模式下都可以。

    [回复]

  2. 张龙华说道:

    你好,请问下,如何用c++写负载均衡啊?或者有开源的项目推荐没?

    [回复]

    朱念洋 回复:

    之前都是在公司内部自己实现负载均衡的。不过基本思路就是我文章里面提到的。

    [回复]

发表评论