• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    PHP实现负载均衡的加权轮询方法分析

    本文实例讲述了PHP实现负载均衡的加权轮询方法。分享给大家供大家参考,具体如下:

    1. 负载均衡算法有哪些?

    2.如何用PHP实现加权轮询?

    实现思路:

    通过传入不同的用户id,然后给他们分配不同的主机。

    首先,需要一个接收用户id的数组。

    其次,需要一个存主机的数组,这些主机有不同的权重。这里的权重可以这么考虑:

    假设有abc三台主机,权重分别为3,1,1,那么a的占比为0.6,b和c的占比各为0.2。

    直接遍历主机的数组,假如用户来了100个人,到a的时候,a的占比是0.6,就从用户数组里随机取60个人分给a;轮到b时,b的占比是0.2,就从用户数组里随机取20人;同理,c20人,这样就完成了100个请求的转发。

    可是真实场景不是固定一批用户,而是持续不断的用户请求,由于转发非常快,当来的新用户非常少时,每次从用户队列中取完、转发后立马去用户队列中取,很有可能每次只取2条,造成请求全部给了a,b和c一直没有的情况。这时候可以考虑按照不同策略从用户队列中取数据。假设以前5ms就处理完一次转发,则现在定义两种策略,如果用户队列中有100个用户时,就取出来,按着主机占比进行转发,如果用户队列中不足100人,但是当前时间和上一次取值时间相差10ms,就取出来进行转发,这样就可以累积5ms,而这5ms里队列中又会多一些用户请求,这样就不会把所有请求都分给一台机器了。

    代码:

    ?php
    // php实现负载均衡的加权轮询(WRR)
    class WRR {
      // 每次取100人
      const num = 100;
      // 上次取值时间,秒级时间戳
      public $last_time;
      // 权重 machine=>weight
      public $machines = array(
        'a' => 3, // 0.6
        'b' => 1, // 0.2
        'c' => 1 // 0.2
      );
      // 占比
      public $proportion = array();
      // 用户队列
      public static $user_ids = array();
      public function __construct() {
        // 各机器的占比
        $total = 0;
        foreach ($this->machines as $machine => $weight) {
          $total += $weight;
        }
        $this->proportion['a'] = $this->machines['a'] / $total;
        $this->proportion['b'] = $this->machines['b'] / $total;
        $this->proportion['c'] = $this->machines['c'] / $total;
      }
      public function getUsers() {
        // 用户人数
        $cnt = count(self::$user_ids);
        $a_num = 0;
        $b_num = 0;
        $c_num = 0;
        if ($cnt >= self::num) { // 队列超过100人
          $a_num = round(self::num * $this->proportion['a']);
          $b_num = round(self::num * $this->proportion['b']);
          $c_num = $cnt - $a_num - $b_num;
        } else { // 队列不足100人
          $last_time = $this->last_time; // 上次访问时间
          while (true) {
            $current_time = $this->getMillisecond();
            if (($current_time - $last_time) >= 10) { // 当前时间和上一次取值时间超过10ms
              $a_num = round($cnt * $this->proportion['a']);
              $b_num = round($cnt * $this->proportion['b']);
              $c_num = $cnt - $a_num - $b_num;
              $this->last_time = self::getMillisecond();  // 更新访问时间
              break;
            }
          }
        }
        $a = array_splice(self::$user_ids, 0, $a_num);
        $b = array_splice(self::$user_ids, 0, $b_num);
        $c = array_splice(self::$user_ids, 0, $c_num);
        return array(
          'a' => $a,
          'b' => $b,
          'c' => $c
        );
      }
      // 获取毫秒级时间戳
      public function getMillisecond() {
        list($t1, $t2) = explode(" ", microtime());
        return (float)sprintf('%.0f', (floatval($t1) + floatval($t2)) * 1000);
      }
    }
    // 测试
    $wrr = new WRR();
    for ($i = 0; $i  3; $i++) {// 模拟持续不断的用户请求
      $random = rand(10, 120);
      $user_ids = range(1, $random);
      WRR::$user_ids = $user_ids;
      $users = $wrr->getUsers();
      print_r($users);
    }
    
    

    真实的算法比这个复杂多了,它需要考虑一点,就是来过的用户要保持原来分配的机器,除非原来的机器挂了。这样做的原因是缓存。很多基于内存的缓存,都是基于用户级别的,所以相同的用户保持同一台机器,有助于提升性能。

    更多关于PHP相关内容感兴趣的读者可查看本站专题:《PHP数据结构与算法教程》、《php程序设计算法总结》、《php字符串(string)用法总结》、《PHP数组(Array)操作技巧大全》、《PHP常用遍历算法与技巧总结》及《PHP数学运算技巧总结》

    希望本文所述对大家PHP程序设计有所帮助。

    您可能感兴趣的文章:
    • Nginx 安装笔记(含PHP支持、虚拟主机、反向代理负载均衡)
    • PHP开发负载均衡指南
    • PHP实现负载均衡下的session共用功能
    • PHP实现负载均衡session共享redis缓存操作示例
    • Thinkphp结合AJAX长轮询实现PC与APP推送详解
    • PHP经典算法集锦【经典收藏】
    • php 分库分表hash算法
    • php的hash算法介绍
    • PHP中对各种加密算法、Hash算法的速度测试对比代码
    • PHP实现的一致性Hash算法详解【分布式算法】
    上一篇:PHP实现负载均衡session共享redis缓存操作示例
    下一篇:Yii2语言国际化自动配置详解
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    PHP实现负载均衡的加权轮询方法分析 PHP,实现,负载,均衡,的,加权,