Beispiel #1
0
 /**
  * 解析模板配置
  *
  * @param $arrData unknown_type       	
  * @param $arrTplConfig unknown_type       	
  * @return boolean
  */
 public function parseTplConfig(&$arrData, $arrTplConfig)
 {
     $arrQueryInfo =& $arrData['uiData']['queryInfo'];
     $arrHilightInfo =& $arrData['uiData']['hilightInfo'];
     $arrControlInfo =& $arrData['uiControl'];
     $arrUrlConfig = $arrQueryInfo['pUrlConfig'];
     // strategy
     unset($arrQueryInfo['strategyName']);
     $bolTnUnFeature = Util::getConf('/feature', 'FEATURE_LIST/TN_UN/TURN') === 'ON' ? true : false;
     if ($bolTnUnFeature) {
         $strTn = empty($arrData['uiData']['queryInfo']['accountName']) ? $GLOBALS['DEFAULT_TEMPLATE_NAME'] : $arrData['uiData']['queryInfo']['accountName'];
         $strStrategyName = shmdict_getValueFromDict($strTn, 'tn_un');
         $arrQueryInfo['strategyName'] = empty($strStrategyName) ? 'baidu' : $strStrategyName;
     } else {
         if (isset($arrTplConfig['strategy'])) {
             $arrQueryInfo['strategyName'] = trim($arrTplConfig['strategy']);
         } else {
             if (!isset($arrQueryInfo['strategyName'])) {
                 $arrQueryInfo['strategyName'] = DEFAULT_TEMPLATE_STRATEGY;
             }
         }
     }
     // services
     unset($arrControlInfo['services_ResultPage']);
     $arrServiceNames = explode(',', ALL_SERVICE);
     $arrServiceNames = array_flip($arrServiceNames);
     if (isset($arrTplConfig['services']) && !empty($arrTplConfig['services'])) {
         $arrServices = explode(',', $arrTplConfig['services']);
         $arrResultPage = array();
         for ($i = 0; $i < MAX_SVR_NUM; $i++) {
             $arrResultPage[$i] = 0;
         }
         foreach ($arrServices as $key) {
             if (isset($arrServiceNames[$key]) && $arrServiceNames[$key] < MAX_SVR_NUM) {
                 $arrResultPage[$arrServiceNames[$key]] = 1;
             }
         }
         $arrControlInfo['services_ResultPage'] = $arrResultPage;
     }
     unset($arrControlInfo['services_FrontPage']);
     if (isset($arrTplConfig['front_services']) && !empty($arrTplConfig['front_services'])) {
         $arrServices = explode(',', $arrTplConfig['front_services']);
         $arrResultPage = array();
         for ($i = 0; $i < MAX_SVR_NUM; $i++) {
             $arrResultPage[$i] = 0;
         }
         foreach ($arrServices as $key) {
             if (isset($arrServiceNames[$key]) && $arrServiceNames[$key] < MAX_SVR_NUM) {
                 $arrResultPage[$arrServiceNames[$key]] = 1;
             }
         }
         $arrControlInfo['services_FrontPage'] = $arrResultPage;
     }
     if (isset($arrTplConfig['ignore_url'])) {
         $arrControlInfo['ignoreUrl'] = intval($arrTplConfig['ignore_url']);
     } else {
         $arrControlInfo['ignoreUrl'] = 0;
     }
     if (isset($arrTplConfig['protectpp'])) {
         $arrControlInfo['protectppSwitch'] = intval($arrTplConfig['protectpp']);
         if ($arrControlInfo['protectppSwitch'] != PROTECTPP_SWITCH_OPEN) {
             $arrControlInfo['protectppSwitch'] = PROTECTPP_SWITCH_CLOSE;
         }
     } else {
         $arrControlInfo['protectppSwitch'] = PROTECTPP_SWITCH_CLOSE;
     }
     // 强制关闭了
     $arrControlInfo['protectppSwitch'] = PROTECTPP_SWITCH_CLOSE;
     if (isset($arrTplConfig['needsp'])) {
         $arrQueryInfo['needSp'] = intval($arrTplConfig['needsp']);
         if ($arrQueryInfo['needSp'] < 0 || $arrQueryInfo['needSp'] > 1) {
             $arrQueryInfo['needSp'] = 0;
         }
     } else {
         $arrQueryInfo['needSp'] = 0;
     }
     if (isset($arrTplConfig['inter_page'])) {
         $arrQueryInfo['interPage'] = intval($arrTplConfig['inter_page']);
     } else {
         $arrQueryInfo['interPage'] = 0;
     }
     if (isset($arrTplConfig['resLimit'])) {
         $arrQueryInfo['resLimitSwitch'] = intval($arrTplConfig['resLimit']);
         if ($arrQueryInfo['resLimitSwitch'] != PROTECTPP_SWITCH_OPEN) {
             $arrQueryInfo['resLimitSwitch'] = PROTECTPP_SWITCH_CLOSE;
         }
     } else {
         $arrQueryInfo['resLimitSwitch'] = PROTECTPP_SWITCH_CLOSE;
     }
     unset($arrQueryInfo['wenkuUrlPara']);
     if (isset($arrTplConfig['special_pagetype_para'])) {
         $strTemp = $arrTplConfig['special_pagetype_para'];
         $arrTemp = str_split($strTemp);
         $bolFlag = true;
         foreach ($arrTemp as $char) {
             if (is_numeric($char) && $char >= 0 && $char <= 9) {
                 continue;
             } else {
                 if ($char == ',' || $char == '|') {
                     continue;
                 } else {
                     $bolFlag = false;
                     break;
                 }
             }
         }
         if ($bolFlag === true) {
             $arrQueryInfo['wenkuUrlPara'] = WENKU_WAP_PC_KEY . '=' . $strTemp;
         }
     }
     /*
      * da所需资源号
      */
     unset($arrQueryInfo['daResource']);
     if (isset($arrTplConfig['da_resource'])) {
         $arrResource = explode(',', $arrTplConfig['da_resource']);
         $arrDaResource = array();
         for ($i = 0; $i < DA_RES_COUNT; $i++) {
             if (isset($arrResource[$i])) {
                 $arrDaResource[$i] = intval($arrResource[$i]);
             } else {
                 $arrDaResource[$i] = 0;
             }
         }
         $arrQueryInfo['daResource'] = $arrDaResource;
     }
     // RS服务请求参数
     $arrQueryInfo['needRsSeResult'] = isset($arrControlInfo['services_ResultPage'][SvrType_RS]) ? $arrControlInfo['services_ResultPage'][SvrType_RS] : 0;
     // ERS服务请求参数
     $intEcomrsOpen = isset($arrQueryInfo['ecomrsOpen']) ? intval($arrQueryInfo['ecomrsOpen']) : 1;
     $intNeedERSResult = isset($arrControlInfo['services_ResultPage'][SvrType_ERS]) ? $arrControlInfo['services_ResultPage'][SvrType_ERS] : 0;
     if ($intEcomrsOpen == 1 && $intNeedERSResult == 1) {
         $arrQueryInfo['needERSResult'] = 1;
     } else {
         $arrQueryInfo['needERSResult'] = 0;
     }
     /*
      * 区分是否为内部流量
      */
     unset($arrQueryInfo['isInternalFlow']);
     if (isset($arrTplConfig['is_internal_flow'])) {
         $intFlowFlag = intval($arrTplConfig['is_internal_flow']);
         if ($intFlowFlag != 0 && $intFlowFlag != 1) {
             $intFlowFlag = 0;
         }
         $arrQueryInfo['isInternalFlow'] = $intFlowFlag;
     }
     if ($arrUrlConfig['f'] == FROM_RS && isset($arrTplConfig['pp_template_for_rs'])) {
         $arrQueryInfo['templateForRs'] = $arrTplConfig['pp_template_for_rs'];
     } else {
         $arrQueryInfo['templateForRs'] = $arrUrlConfig['tn'];
     }
     $arrEcSrc = array();
     $intEcNum = 0;
     if (isset($arrTplConfig['ec_serial']) && !empty($arrTplConfig['ec_serial'])) {
         $arrTemp = explode(',', $arrTplConfig['ec_serial']);
         $count = 0;
         foreach ($arrTemp as $index => $value) {
             if ($count >= MAX_EC_SRC_NUM) {
                 break;
             }
             $arrEcSrc[$index]['id'] = intval($value);
             $count++;
         }
         $intEcNum = $count;
     }
     if (isset($arrTplConfig['ec_templates']) && !empty($arrTplConfig['ec_templates'])) {
         $arrTemp = explode(',', $arrTplConfig['ec_templates']);
         $count = 0;
         foreach ($arrTemp as $index => $value) {
             if ($count >= MAX_EC_SRC_NUM) {
                 break;
             }
             $arrEcSrc[$index]['template_name'] = trim($value);
             $count++;
         }
         if ($count < $intEcNum) {
             $intEcNum = $count;
         }
     }
     if ($intEcNum <= 0) {
         $intEcNum = 1;
         $arrEcSrc[0]['id'] = 2;
         $arrEcSrc[0]['template_name'] = "baidufsheadps";
     }
     $arrSrcId = array();
     $arrEcSrcs = array();
     for ($i = 0; $i < $intEcNum; $i++) {
         $arrSrcId[] = $arrEcSrc[$i]['id'];
         $arrEcSrcs[$i]['id'] = isset($arrEcSrc[$i]['id']) ? intval($arrEcSrc[$i]['id']) : 0;
         $arrEcSrcs[$i]['req_num'] = isset($arrEcSrc[$i]['req_num']) ? intval($arrEcSrc[$i]['req_num']) : 0;
         $arrEcSrcs[$i]['ad_offset'] = isset($arrEcSrc[$i]['ad_offset']) ? intval($arrEcSrc[$i]['ad_offset']) : 0;
         $arrEcSrcs[$i]['charge_name'] = isset($arrEcSrc[$i]['charge_name']) ? $arrEcSrc[$i]['charge_name'] : '';
         $arrEcSrcs[$i]['template_name'] = isset($arrEcSrc[$i]['template_name']) ? $arrEcSrc[$i]['template_name'] : 0;
         $arrEcSrcs[$i]['user_def'] = isset($arrEcSrc[$i]['user_def']) ? $arrEcSrc[$i]['user_def'] : '';
         $arrEcSrcs[$i]['printInfo'] = isset($arrEcSrc[$i]['printInfo']) ? $arrEcSrc[$i]['printInfo'] : '';
     }
     $arrQueryInfo['srcId'] = $arrSrcId;
     $arrQueryInfo['ec_src'] = $arrEcSrcs;
     // ASP服务迁移
     $arrQueryInfo['needASPResult'] = isset($arrControlInfo['services_ResultPage'][SvrType_EC]) ? $arrControlInfo['services_ResultPage'][SvrType_EC] : 0;
     // confuse 广告和大搜索一致
     // 		if (isset ( $arrTplConfig ['confuseResult'] )) {
     // 			$arrQueryInfo ['confuse_Switch'] = intval ( $arrTplConfig ['confuseResult'] );
     // 			if ($arrQueryInfo ['confuse_Switch'] != PROTECTPP_SWITCH_OPEN) {
     // 				$arrQueryInfo ['confuse_Switch'] = PROTECTPP_SWITCH_CLOSE;
     // 			}
     // 		} else {
     // 			$arrQueryInfo ['confuse_Switch'] = PROTECTPP_SWITCH_CLOSE;
     // 		}
     /*****************************anti360 临时逻辑***************************************/
     /**
      * 0-关闭    1-全开启     2-部分开启    非法或没传时默认0
      */
     if (isset($arrTplConfig['confuseResult'])) {
         $intConfuseResult = intval($arrTplConfig['confuseResult']);
         if ($intConfuseResult == PROTECTPP_SWITCH_OPEN || $intConfuseResult == PROTECTPP_SWITCH_PART_OPEN) {
             $arrQueryInfo['confuse_Switch'] = $intConfuseResult;
         } else {
             $arrQueryInfo['confuse_Switch'] = PROTECTPP_SWITCH_CLOSE;
         }
     } else {
         $arrQueryInfo['confuse_Switch'] = PROTECTPP_SWITCH_CLOSE;
     }
     /*********************************************************************************/
     // 是否需要AS结果,包括AC和阿拉丁以及至知心
     $arrQueryInfo['need_as_result'] = isset($arrControlInfo['services_ResultPage'][SvrType_AS]) ? $arrControlInfo['services_ResultPage'][SvrType_AS] : 0;
     // 结构化和阿拉丁飘红
     $arrQueryInfo['protectPPSwitch'] = $arrControlInfo['protectppSwitch'];
     // 设置templateConfig
     $arrData['uiData']['templateConfig'] = $arrTplConfig;
     var_dump($arrData);
     // 设置hilight信息
     unset($arrHilightInfo['hiFixInfo']['hilight_prefix']);
     if (isset($arrTplConfig['hilight_prefix'])) {
         $arrHilightInfo['hiFixInfo']['hilight_prefix'] = trim($arrTplConfig['hilight_prefix']);
     }
     unset($arrHilightInfo['hiFixInfo']['hilight_postfix']);
     if (isset($arrTplConfig['hilight_postfix'])) {
         $arrHilightInfo['hiFixInfo']['hilight_postfix'] = trim($arrTplConfig['hilight_postfix']);
     }
     unset($arrHilightInfo['hiFixInfo']['bold_prefix']);
     if (isset($arrTplConfig['bold_prefix'])) {
         $arrHilightInfo['hiFixInfo']['bold_prefix'] = trim($arrTplConfig['bold_prefix']);
     }
     unset($arrHilightInfo['hiFixInfo']['bold_postfix']);
     if (isset($arrTplConfig['bold_postfix'])) {
         $arrHilightInfo['hiFixInfo']['bold_postfix'] = trim($arrTplConfig['bold_postfix']);
     }
     return true;
 }
Beispiel #2
0
 /**
  *  mod=1/2的请求,需要检测是否命中品专词典,若命中则直接返回白页,并要求FE跳转至同步页面
  */
 public function checkHitPinzhuan(&$arrIsParams, $strQueryWord)
 {
     if (in_array($arrIsParams['mod'], array(IS_PRE_REQ, IS_NORMAL_REQ, IS_PRE_DICT_REQ))) {
         //HIS,命中词典直接跳同步
         if ($arrIsParams['isbd'] !== 1) {
             $bolHitPinzhuan = shmdict_getValueFromDict($strQueryWord, 'pinzhuan');
             if ($bolHitPinzhuan == 1) {
                 $arrIsParams['status'] = IS_HIT_PINZHUAN;
                 return true;
             }
         } else {
             $intDictRst = shmdict_getValueFromDict($strQueryWord, 'pinzhuan_is');
             switch ($intDictRst) {
                 //IS,值为1时直接跳同步
                 case 1:
                     $arrIsParams['status'] = IS_HIT_PINZHUAN;
                     return true;
                     //IS,值为2时出空白页。只对IS_2nd,预测请求生效
                 //IS,值为2时出空白页。只对IS_2nd,预测请求生效
                 case 2:
                     if (in_array($arrIsParams['mod'], array(IS_PRE_REQ, IS_PRE_DICT_REQ))) {
                         $arrIsParams['status'] = IS_HIT_PINZHUAN_BLANK;
                         return true;
                     }
                 default:
                     return false;
             }
         }
     }
 }
Beispiel #3
0
/**
 * 并行渲染
 * @param unknown_type $data
 * @param unknown_type $smarty
 * @param unknown_type uiData中阿拉丁的数据
 * @param unknown_type uiData中普通结果的数据
 */
function multi_render($data, $smarty, $arrAlaData, $arrAsData, $arrMultiRenderConf)
{
    $time_start = Volatile::microtime(true) * 1000;
    require VUI_APP_PATH . '/plugins/modifier.common_render.php';
    $arrNeedRenderSingleResult = array_merge($arrAlaData, $arrAsData);
    $time_multi_start = Volatile::microtime(true) * 1000;
    $mh = curl_multi_init();
    $url = $arrMultiRenderConf['MULTI_RENDER_URL'];
    $arrRenderMultiReq = array();
    $arrMultiPublicData = array();
    $arrMultiPublicData['smarty_conf'] = CSmarty::getConf();
    $arrMultiPublicData['DISPLAY'] = $GLOBALS['DISPLAY'];
    $arrMultiPublicData['LOG'] = $GLOBALS['LOG'];
    $arrMultiPublicData['DEFAULT_TEMPLATE_NAME'] = $GLOBALS['DEFAULT_TEMPLATE_NAME'];
    $arrMultiPublicData['DEFAULT_TEMPLATE_TYPE'] = $GLOBALS['DEFAULT_TEMPLATE_TYPE'];
    $arrMultiPublicData['ALADDIN_TEMPLATE_TYPE'] = $GLOBALS['ALADDIN_TEMPLATE_TYPE'];
    $arrMultiPublicData['STRUCT_TEMPLATE_TYPE'] = $GLOBALS['STRUCT_TEMPLATE_TYPE'];
    $arrMultiPublicData['ECOM_TEMPLATE_TYPE'] = $GLOBALS['ECOM_TEMPLATE_TYPE'];
    $arrMultiPublicData['randTime'] = CSmarty::getRandState();
    $arrMultiPublicData['TplLOG'] = $GLOBALS['TplLOG'];
    $arrMultiPublicData['ALADDIN_FIELD'] = $GLOBALS['ALADDIN_FIELD'];
    $arrMultiPublicData['globalConf'] = $GLOBALS['globalConf'];
    $data['uiData']['multi_public_data'] = $arrMultiPublicData;
    //使用logid来计算存放在共享内存中的key
    $intLogId = CLog::logId();
    $memsize = intval($arrMultiRenderConf['SHMOP']['MEM_SIZE']);
    // 共享内存的大小,单位byte
    $perm = 0666;
    // 共享内存访问权限,参考linux的权限
    $shmid = shmop_open($intLogId, "n", $perm, $memsize);
    // 创建一个共享内存,第二个参数c表示创建
    $shm_bytes_written = shmop_write($shmid, addslashes(serialize($data['uiData'])), 0);
    $arrShmData['id'] = $intLogId;
    $arrShmData['size'] = $shm_bytes_written;
    unset($data['uiData']['multi_public_data']);
    //若向共享内存中存放数据失败,则直接跳出并行渲染,回归正常渲染
    if ($arrShmData['id'] === false || empty($arrShmData['size'])) {
        CLog::warning("put data to shmop fail,back to nomarl render,data_size:" . strlen(addslashes(serialize($data['uiData']))), MULTI_RENDER_FAIL);
        return false;
    }
    $GLOBALS['multi_render_shmid'] = $shmid;
    //主模板加入并发队列
    $strReqKey = 'req_main';
    $arrMainPostData = array();
    $intRandTime = CSmarty::getRandState();
    $arrMainPostData['tempName'] = $data['uiControl']['templateName'];
    $arrMainPostData['tempSwitch'] = $data['uiControl']['templateSwitch'];
    $arrMainPostData['tempVersion'] = empty($data['uiControl']['templateVersion']) ? "" : $data['uiControl']['templateVersion'];
    $arrMainPostData['dataId'] = $arrShmData['id'];
    $arrMainPostData['dataSize'] = $arrShmData['size'];
    $arrMainPostData['randTime'] = $intRandTime;
    $hexQid = $data['uiData']['queryInfo']['queryId'];
    $strMainUrl = $url . '?renderType=' . $strReqKey . '&logId=' . $intLogId . '&qid=' . $hexQid;
    $intMainTplTimeout = intval($arrMultiRenderConf['MAIN_TPL_TIMEOUT_MS']);
    $arrRenderMultiReq[$strReqKey] = curl_init($strMainUrl);
    curl_setopt($arrRenderMultiReq[$strReqKey], CURLOPT_HEADER, 0);
    curl_setopt($arrRenderMultiReq[$strReqKey], CURLOPT_NOSIGNAL, true);
    curl_setopt($arrRenderMultiReq[$strReqKey], CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($arrRenderMultiReq[$strReqKey], CURLOPT_POST, 1);
    curl_setopt($arrRenderMultiReq[$strReqKey], CURLOPT_HTTPHEADER, array('Expect:'));
    curl_setopt($arrRenderMultiReq[$strReqKey], CURLOPT_POSTFIELDS, http_build_query($arrMainPostData));
    curl_setopt($arrRenderMultiReq[$strReqKey], CURLOPT_TIMEOUT_MS, $intMainTplTimeout);
    curl_multi_add_handle($mh, $arrRenderMultiReq[$strReqKey]);
    //按时间分包(尽可能均分),时间参数来自于进生的模板耗时报表
    //分包数量,主模板单独占用一个包
    $intSplitNum = intval($arrMultiRenderConf['PACK_NUM']) - 1;
    $arrTplTime = array();
    $intTimeCount = 0;
    $arrSplitReqData = array();
    // 分阿拉丁
    if (!empty($arrAlaData) && is_array($arrAlaData)) {
        $intDefaultAladdinTime = $arrMultiRenderConf['DEFAULT_ALADDIN_TIME'];
        $bHhvm = $GLOBALS['globalConf']['FEATURE_LIST']['HHVM_BRANCH']['TURN'] === 'ON' ? true : false;
        if ($bHhvm) {
            $getDict = new GetDict();
            $getDict->init(DATA_PATH . "/shmdict/dict/tpl_time.php");
        }
        foreach ($arrAlaData as $strKey => $arrOneAlaData) {
            if ($bHhvm) {
                //hhvm 临时方案,提前手动分发tpl_time.php文件到data/shmdict/dict/下
                $intOneTplTime = $getDict->getValueFromDict($arrOneAlaData['render_template']);
            } else {
                $intOneTplTime = shmdict_getValueFromDict($arrOneAlaData['render_template'], 'tpl_time');
            }
            $intOneTplTime = empty($intOneTplTime) ? $intDefaultAladdinTime : $intOneTplTime;
            $intTimeCount += $intOneTplTime;
            $arrTplTime[$strKey] = $intOneTplTime;
        }
        arsort($arrTplTime);
        $intSplitTplTime = ceil($intTimeCount / $intSplitNum);
        $arrGroupTime = array();
        $intIndex = 0;
        foreach ($arrTplTime as $strKey => $arrOneTplTime) {
            $intIndex = $intIndex % $intSplitNum;
            $intCount = 0;
            while ($intCount < $intSplitNum) {
                if ($arrGroupTime[$intIndex] >= $intSplitTplTime) {
                    $intIndex = ($intIndex + 1) % $intSplitNum;
                } else {
                    $arrSplitReqData[$intIndex][$strKey] = $arrAlaData[$strKey];
                    $arrGroupTime[$intIndex] += $arrOneTplTime;
                    $intIndex++;
                    break;
                }
                $intCount++;
            }
        }
    }
    // 分AS结果
    if (!empty($arrAsData) && is_array($arrAsData)) {
        $intDefaultAsTime = $arrMultiRenderConf['DEFAULT_AS_TIME'];
        $intAsCount = count($arrAsData);
        $intNewTimeCount = $intTimeCount + $intAsCount * $intDefaultAsTime;
        $intNewSplitTplTime = $intNewTimeCount / $intSplitNum;
        foreach ($arrAsData as $strKey => $arrOneAsData) {
            $intIndex = $intIndex % $intSplitNum;
            $intCount = 0;
            while ($intCount < $intSplitNum) {
                if ($arrGroupTime[$intIndex] >= $intNewSplitTplTime) {
                    $intIndex = ($intIndex + 1) % $intSplitNum;
                } else {
                    $arrSplitReqData[$intIndex][$strKey] = $arrOneAsData;
                    $arrGroupTime[$intIndex] += $intDefaultAsTime;
                    $intIndex++;
                    break;
                }
                $intCount++;
            }
        }
    }
    //将单条结果包加入并行
    if (empty($arrSplitReqData) || !is_array($arrSplitReqData)) {
        CLog::warning("split pack result is empty,back to nomarl render!", MULTI_RENDER_FAIL);
        $bolDelRst = shmop_delete($shmid);
        $bolCloseRst = shmop_close($shmid);
        if ($bolDelRst && $bolCloseRst) {
            unset($GLOBALS['multi_render_shmid']);
        }
        return false;
    }
    foreach ($arrSplitReqData as $intPackIndex => $arrOneSplitReqData) {
        if (!empty($arrOneSplitReqData) && is_array($arrOneSplitReqData)) {
            $strReqKey = 'req_' . $intPackIndex;
            $arrReqPostData = array();
            $arrReqPostData['dataId'] = $arrShmData['id'];
            $arrReqPostData['dataSize'] = $arrShmData['size'];
            $arrReqPostData['randTime'] = $intRandTime;
            $arrReqPostData['dataInfo'] = $arrOneSplitReqData;
            $strReqUrl = $url . '?renderType=' . $strReqKey . '&logId=' . $intLogId . '&qid=' . $hexQid;
            $arrRenderMultiReq[$strReqKey] = curl_init($strReqUrl);
            $intReqNum = count($arrOneSplitReqData);
            $intReqNumLine = intval($arrMultiRenderConf['SINGLE_TIMEOUT_NUM_LINE']);
            $intMoreNumPackTimeout = intval($arrMultiRenderConf['SINGLE_TPL_PACK_MAX_TIMEOUT_MS']);
            $intLessNumPackTimeout = intval($arrMultiRenderConf['SINGLE_TPL_PACK_MIN_TIMEOUT_MS']);
            $intTimeOut = $intReqNum > $intReqNumLine ? $intMoreNumPackTimeout : $intLessNumPackTimeout;
            curl_setopt($arrRenderMultiReq[$strReqKey], CURLOPT_HEADER, 0);
            curl_setopt($arrRenderMultiReq[$strReqKey], CURLOPT_NOSIGNAL, true);
            curl_setopt($arrRenderMultiReq[$strReqKey], CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($arrRenderMultiReq[$strReqKey], CURLOPT_POST, 1);
            curl_setopt($arrRenderMultiReq[$strReqKey], CURLOPT_HTTPHEADER, array('Expect:'));
            curl_setopt($arrRenderMultiReq[$strReqKey], CURLOPT_POSTFIELDS, http_build_query($arrReqPostData));
            curl_setopt($arrRenderMultiReq[$strReqKey], CURLOPT_TIMEOUT_MS, $intTimeOut);
            curl_multi_add_handle($mh, $arrRenderMultiReq[$strReqKey]);
        }
    }
    $GLOBALS['logArr']['time_multi_render_ready'] = round(Volatile::microtime(true) * 1000 - $time_start, 2);
    //执行并行渲染
    $time_exe_start = Volatile::microtime(true) * 1000;
    $mrc = curl_multi_exec($mh, $active);
    if ($mrc == CURLM_CALL_MULTI_PERFORM) {
        CLog::warning("curl_multi connect fail,back to nomarl render!", MULTI_RENDER_FAIL);
        return false;
    }
    $intMaxCurlExeTimes = intval($arrMultiRenderConf['CURL_MAX_EXE_TIMES']);
    $intCurlExeCount = 0;
    while ($active && $mrc == CURLM_OK && $intCurlExeCount < $intMaxCurlExeTimes) {
        $intCurlExeCount++;
        if (curl_multi_select($mh) != -1) {
            $mrc = curl_multi_exec($mh, $active);
            if ($mrc == CURLM_CALL_MULTI_PERFORM) {
                CLog::warning("curl_multi connect fail,back to nomarl render!", MULTI_RENDER_FAIL);
                return false;
            }
        }
    }
    $GLOBALS['logArr']['time_multi_render_exec'] = round(Volatile::microtime(true) * 1000 - $time_exe_start, 2);
    $time_start = Volatile::microtime(true) * 1000;
    //接收数据
    foreach ($arrRenderMultiReq as $key => $value) {
        $arrRenderResult[$key] = curl_multi_getcontent($arrRenderMultiReq[$key]);
        curl_close($arrRenderMultiReq[$key]);
        curl_multi_remove_handle($mh, $arrRenderMultiReq[$key]);
    }
    curl_multi_close($mh);
    $isDebug = $bolPreRenderFeature = $arrMultiRenderConf['DEBUG'] == 'ON' ? true : false;
    $arrRenderedData = array();
    $intChildLastIn = 0;
    $intChildLastOut = 0;
    $intChildFirstIn = 0;
    $intTCount = 1;
    $strAllOneTime = '';
    $arrTplLog = array();
    $arrResultTplTm = array();
    $intTimeRenderStructTpl = 0;
    $intRenderStructTplNum = 0;
    $intTimeAladdinTotal = 0;
    $intRenderAladdinNum = 0;
    $intTimeUrlencryptTotal = 0;
    $arrOtherLog = array();
    foreach ($arrRenderResult as $key => $oneResult) {
        $arrUnseriResult = unserialize($oneResult);
        if (!empty($arrUnseriResult)) {
            $arrLogInfo = $arrUnseriResult['pack_log'];
            unset($arrUnseriResult['pack_log']);
            if (!empty($arrLogInfo) && is_array($arrLogInfo)) {
                $intChildLastIn = $arrLogInfo['start_time'] > $intChildLastIn ? $arrLogInfo['start_time'] : $intChildLastIn;
                if ($key != 'req_main') {
                    $GLOBALS['logArr']['time_pack_' . $intTCount] = round($arrLogInfo['end_time'] - $arrLogInfo['start_time'], 2);
                    $intTCount++;
                } else {
                    $GLOBALS['logArr']['time_render_main_tpl'] = $arrLogInfo['time_main_tpl'];
                    $GLOBALS['logArr']['time_pack_main'] = round($arrLogInfo['end_time'] - $arrLogInfo['start_time'], 2);
                }
                $arrTplLog = empty($arrTplLog) ? $arrLogInfo['tpl_log'] : array_merge($arrTplLog, $arrLogInfo['tpl_log']);
                $arrResultTplTm = empty($arrResultTplTm) ? $arrLogInfo['result_tpl_tm'] : array_merge($arrResultTplTm, $arrLogInfo['result_tpl_tm']);
                $intTimeRenderStructTpl += $arrLogInfo['time_render_struct_tpl'];
                $intRenderStructTplNum += $arrLogInfo['render_struct_tpl_num'];
                $intTimeAladdinTotal += $arrLogInfo['time_aladdin_total'];
                $intRenderAladdinNum += $arrLogInfo['render_aladdin_num'];
                $intTimeUrlencryptTotal += $arrLogInfo['time_urlencrypt_total'];
                if (!empty($arrLogInfo['logArr'])) {
                    $arrOtherLog = array_merge($arrOtherLog, $arrLogInfo['logArr']);
                }
                // debug,更为详细的日志信息
                if ($isDebug) {
                    if ($intChildFirstIn == 0) {
                        $intChildFirstIn = $arrLogInfo['start_time'];
                    } else {
                        $intChildFirstIn = $arrLogInfo['start_time'] < $intChildFirstIn ? $arrLogInfo['start_time'] : $intChildFirstIn;
                    }
                    $intChildLastOut = $arrLogInfo['end_time'] > $intChildLastOut ? $arrLogInfo['end_time'] : $intChildLastOut;
                    foreach ($arrLogInfo['one_time'] as $key => $intOneTime) {
                        $strAllOneTime .= $key . ':' . $intOneTime . '|';
                    }
                }
            }
            $arrRenderedData = array_merge($arrRenderedData, $arrUnseriResult);
        } else {
            CLog::warning("whole pack render fail!pack name:" . $key, MULTI_RENDER_FAIL);
        }
    }
    $GLOBALS['logArr'] = array_merge($GLOBALS['logArr'], $arrOtherLog);
    $GLOBALS['logArr']['time_multi_render_web'] = round($intChildLastIn - $time_exe_start, 2);
    $GLOBALS['logArr']['time_multi_render_recdata'] = round(Volatile::microtime(true) * 1000 - $time_start, 2);
    CSmarty::addStructTplRenderNumCount($intRenderStructTplNum);
    CSmarty::addStructTplRenderTimeCount($intTimeRenderStructTpl);
    $GLOBALS['time_count_temp']['time_aladdin_total'] += $intTimeAladdinTotal;
    $GLOBALS['time_count_temp']['render_aladdin_num'] += $intRenderAladdinNum;
    $GLOBALS['time_count_temp']['time_urlencrypt_total'] += $intTimeUrlencryptTotal;
    if (!empty($arrResultTplTm) && is_array($arrResultTplTm)) {
        foreach ($arrResultTplTm as $intOneTplTm) {
            CSmarty::recordResultTplRenderTime($intOneTplTm);
        }
    }
    if (!empty($arrTplLog) && is_array($arrTplLog)) {
        $objTplLog = TplLog::getInstance();
        $objTplLog->setTplData($arrTplLog);
    }
    if ($isDebug) {
        $GLOBALS['logArr']['time_one_detail_time'] = $strAllOneTime;
        $GLOBALS['logArr']['time_web_curl'] = round($intChildFirstIn - $time_exe_start, 2);
        $GLOBALS['logArr']['time_multi_recdata'] = round(Volatile::microtime(true) * 1000 - $intChildLastOut, 2);
        $GLOBALS['logArr']['time_child_max'] = round($intChildLastOut - $intChildFirstIn, 2);
    }
    $time_start = Volatile::microtime(true) * 1000;
    $bolDelRst = shmop_delete($shmid);
    shmop_close($shmid);
    if (!$bolDelRst) {
        CLog::warning("clean shmop fail!id:" . $shmid, MULTI_RENDER_FAIL);
    } else {
        unset($GLOBALS['multi_render_shmid']);
    }
    //主模板并行渲染未成功
    if ($arrRenderedData['req_main']['status'] !== 0) {
        CLog::warning("multi render main tpl fail,try local render once!", MULTI_RENDER_FAIL);
        $GLOBALS['mulit_render_flag'] = 1;
        $page = $smarty->do_render($data['uiData'], $data['uiControl']['templateName'], $data['uiControl']['templateSwitch'], $data['uiControl']['templateVersion']);
        if (empty($page)) {
            CLog::warning("local render main tpl fail too,abandon treatment,back to nomarl render", MULTI_RENDER_FAIL);
            return false;
        }
    } else {
        $page = $arrRenderedData['req_main']['content'];
    }
    unset($arrRenderedData['req_main']);
    $arrReplaceKeys = array();
    $arrReplaceValues = array();
    $intFailNum = 0;
    $strFailKeys = '';
    foreach ($arrRenderedData as $strKey => $strRenderContent) {
        //单条模板未渲染成功
        if ($strRenderContent['status'] !== 0) {
            //CLog::warning("multi render single tpl fail,try local render once!key:" . $strKey, MULTI_RENDER_FAIL);
            $intFailNum++;
            $strFailKeys = empty($strFailKeys) ? $strKey : $strFailKeys . '#' . $strKey;
            $strRenderContent['content'] = render_single_result($strKey, $arrNeedRenderSingleResult, $data);
        }
        if (empty($strRenderContent['content'])) {
            CLog::warning("local render single tpl fail too,abandon treatment,remove this single result!key:" . $strKey, MULTI_RENDER_FAIL);
        }
        $arrReplaceKeys[] = $strKey;
        $arrReplaceValues[] = empty($strRenderContent['content']) ? '' : $strRenderContent['content'];
        unset($arrNeedRenderSingleResult[$strKey]);
    }
    if (!empty($arrNeedRenderSingleResult)) {
        foreach ($arrNeedRenderSingleResult as $strKey => $arrContent) {
            //CLog::warning("multi render single tpl fail,try local render once!key:" . $strKey, MULTI_RENDER_FAIL);
            $intFailNum++;
            $strFailKeys = empty($strFailKeys) ? $strKey : $strFailKeys . '#' . $strKey;
            $rst = render_single_result($strKey, $arrNeedRenderSingleResult, $data);
            if (empty($rst)) {
                CLog::warning("local render single tpl fail too,abandon treatment,remove this single result!key:" . $strKey, MULTI_RENDER_FAIL);
            }
            $arrReplaceKeys[] = $strKey;
            $arrReplaceValues[] = empty($rst) ? '' : $rst;
        }
    }
    if ($intFailNum != 0) {
        CLog::warning("local render single tpl, num[{$intFailNum}] keys[{$strFailKeys}]", MULTI_RENDER_FAIL);
    }
    $GLOBALS['logArr']['time_multi_render_retry'] = round(Volatile::microtime(true) * 1000 - $time_start, 2);
    $time_start = Volatile::microtime(true) * 1000;
    $page = Util::replace($page, $arrReplaceKeys, $arrReplaceValues, 0);
    $GLOBALS['logArr']['time_multi_render_repdata'] = round(Volatile::microtime(true) * 1000 - $time_start, 2);
    return $page;
}