三. 代码流程分析

组件模块从代码执行流程上来看,主要包括:

  1. 对象实例化

  2. 数据包组装

  3. 保存数据结构

  4. 发送数据包

3.1 对象实例化(已审查)

组件采用单对象实例设计,主要的判断逻辑如下:

相关模型代码如下:

    public static function getLoger()
    {
        if (!isset(self::$Loger)) {
            self::$Loger = new self();
        }
        return self::$Loger;
    }

3.2 数据包组装(构造 $logPacker)(已审查)

这里的数据包组装并不是直接组装成最终的字符串,而是组装为数据结构体,结构包括metrics_name、typeInfo、指标量这三部分,相关模型代码如下:

    public static function encode_count_metrics($metrics_name,$serviceName,$labelType=[],$siteName,$countNum=1,$biz_parameter=''){
        $ret = array();
        $ret[]=$metrics_name;
        $part2 = 'type='.implode('.',$labelType).'&service='.$serviceName.'&site='.$siteName;
        if (!empty($biz_parameter)){
            $part2.='&biz_parameter='.$biz_parameter;
        }
        $ret[]=$part2;
        $ret[]=$countNum;
        return $ret;
    }

3.3 保存数据结构 (消费 $logPacker)(已审查)

这个是关键的一步,它的作用在于把数据包结构数据进行再一次结构化,变为真正可用的全局数据结构,总体结构如下图:

相关代码模型如下:

    private function save_count_metrics_log($logPacker)
    {
        $log = implode('|', $logPacker) . "\n";

        $log_size = strlen($log);
        switch (self::$PACKER_SAVE_TYPE) {
            case 'STATIC_VAR':
                self::$count_metrics_logs['LOGS_DATA']['log_str'][] = $log;
                self::$count_metrics_logs['LOGS_DATA']['log_struct'][] = $logPacker;
                self::$count_metrics_logs['LOGS_DATA']['log_length'][] = $log_size;
                self::$count_metrics_logs['TOTAL_COUNT']++;
                self::$count_metrics_logs['TOTAL_SIZE'] += $log_size;
                break;
            case 'SHM':
                break;
            case 'APCU':
                break;
        }

    }

3.4 发送数据包 (通过UDP协议)(已审查)

数据包采用两种模式进行发送,一种是SIMPLE模式,这种模式是对每一条数据包均进行发送,第二种是GROUP模式,顾名思义就是数据量达到了一定限制后再统一发送,组件默认采用GROUP模式进行发送。

组件在保存数据结构后会自动出发数据包发送流程,GROUP模式下只有当数据总量达到配置中设置的数据包最大值时才会激发UDP发送过程,残余的数据会在类析构函数中进行发送。

GROUP发送模式下相关的发送流程如下图所示:

GROUP发送相关的模型代码如下:

    if (self::$count_metrics_logs['TOTAL_SIZE'] >= self::$PACKER_MAX_SIZE) {

      $udpPakData = '';
       try {

          foreach (self::$count_metrics_logs['LOGS_DATA']['log_str'] as $key => $val) {

               $udpPakData .= $val;
               $log_size = self::$count_metrics_logs['LOGS_DATA']['log_length'][$key];

                //垃圾清理
               unset(self::$count_metrics_logs['LOGS_DATA']['log_str'][$key]);
               unset(self::$count_metrics_logs['LOGS_DATA']['log_length'][$key]);
               unset(self::$count_metrics_logs['LOGS_DATA']['log_struct'][$key]);
               self::$count_metrics_logs['TOTAL_COUNT']--;
               self::$count_metrics_logs['TOTAL_SIZE'] -= $log_size;
            }

            self::sendUdpPackage(self::$IP, self::$PORT, $udpPakData); //发送UDP

            return 0;

            } catch (\Exception $e) {

                return $e->getCode();  //这里返回错误码,而不是继续向上返回异常。

            }
      }
文档更新时间: 2018-08-27 02:32   作者:李彪