濮阳杆衣贸易有限公司

主頁 > 知識(shí)庫 > PHP多線程模擬實(shí)現(xiàn)秒殺搶單

PHP多線程模擬實(shí)現(xiàn)秒殺搶單

熱門標(biāo)簽:深圳外呼系統(tǒng)收費(fèi) 南寧高頻外呼回?fù)芟到y(tǒng)哪家好 長(zhǎng)沙crm外呼系統(tǒng)業(yè)務(wù) 400電話辦理福州市 江蘇外呼電銷機(jī)器人報(bào)價(jià) 電話機(jī)器人危險(xiǎn)嗎 專業(yè)電話機(jī)器人批發(fā)商 離石地圖標(biāo)注 400電話申請(qǐng)方法收費(fèi)

應(yīng)集團(tuán)要求給服務(wù)號(hào)做了個(gè)搶單秒殺的功能,需要對(duì)秒殺做個(gè)測(cè)試,想試試PHP多線程,就模擬了下?lián)寙喂δ堋?/p>

先說秒殺模塊的思路:

正常情況下的用戶秒殺操作

1、發(fā)起秒殺請(qǐng)求
2、進(jìn)入秒殺隊(duì)列
3、隨機(jī)滯后 1 - 2 秒進(jìn)行秒殺結(jié)果查詢請(qǐng)求(算是變相分流吧)
4、成功則生成訂單
5、返回結(jié)果

以下是模擬秒殺的代碼:

?php


set_time_limit(0);

/**
* 線程的執(zhí)行任務(wù)
*/
class Threadrun extends Thread
{
  public $url;
  public $data;
  public $params;

  public function __construct($url, $params=[])
  {
   $this->url = $url;
   $this->params = $params;
  }

  public function run()
  {
   if(($url = $this->url))
   {
     $params = [
      'goods_id'  => 1,
      'activity_id'  => 1,
      'user_id'   => isset($this->params['user_id']) ? $this->params['user_id'] : $this->getCurrentThreadId(),
     ];
     $startTime = microtime(true);
     $this->data = [
      'id'   => $params['user_id'],
      'result'  => model_http_curl_get( $url, $params ),
      'time'  => microtime(true)-$startTime,
      'now'   => microtime(true),
     ];
   }
  }
}

/**
* 執(zhí)行多線程
*/
function model_thread_result_get($urls_array)
{
  foreach ($urls_array as $key => $value)
  {
   $threadPool[$key] = new Threadrun($value["url"],['user_id'=>$value['user_id']]);
   $threadPool[$key]->start();
  }
  foreach ($threadPool as $thread_key => $thread_value)
  {
   while($threadPool[$thread_key]->isRunning())
   {
     usleep(10);
   }
   if($threadPool[$thread_key]->join())
   {
     $variable_data[$thread_key] = $threadPool[$thread_key]->data;
   }
  }
  return $variable_data;
}

/**
* 發(fā)送 HTTP 請(qǐng)求
*/
function model_http_curl_get($url,$data=[],$userAgent="")
{
  $userAgent = $userAgent ? $userAgent : 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2)';
  $curl = curl_init();
  curl_setopt($curl, CURLOPT_URL, $url);
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($curl, CURLOPT_TIMEOUT, 5);
  curl_setopt($curl, CURLOPT_USERAGENT, $userAgent);
  curl_setopt($curl, CURLOPT_POST, true);
  if( !empty($data) ) {
   curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
  }
  $result = curl_exec($curl);
  curl_close($curl);
  return $result;
}


/**
 * 友好的打印變量
 * @param $val
 */
function dump( $val )
{
  echo 'pre>';
  var_dump($val);
  echo '/pre>';
}

/**
 * 寫日志
 * @param $msg
 * @param string $logPath
 */
function writeLog( $msg, $logPath='' ) {
  if( empty($logPath) ) {
   $logPath = date('Y_m_d').'.log';
  }
  if( !file_exists($logPath) ) {
   $fp = fopen( $logPath,'w' );
   fclose( $fp );
  }
  error_log( $msg.PHP_EOL, 3, $logPath);
}

/**
 * 生成日志信息
 * @param $result
 * @param $timeDiff
 * @return bool|string
 */
function createLog( $result, $timeDiff ){
  if( empty($result) || !is_array($result) ) {
   return false;
  }
  $succeed = 0;
  $fail = 0;
  foreach( $result as $v ) {
   $times[] = $v['time'];
   $v['result'] === false ? $fail++ : $succeed++;
  }
  $totalTime = array_sum( $times );
  $maxTime = max( $times );
  $minTime = min( $times );
  $sum = count( $times );
  $avgTime = $totalTime/$sum;
  $segment = str_repeat('=',100);
  $flag = $segment . PHP_EOL;
  $flag .= '總共執(zhí)行時(shí)間:' . $timeDiff . PHP_EOL ;
  $flag .= '最大執(zhí)行時(shí)間:' . $maxTime . PHP_EOL;
  $flag .= '最小執(zhí)行時(shí)間:' . $minTime . PHP_EOL;
  $flag .= '平均請(qǐng)求時(shí)間:' . $avgTime . PHP_EOL;
  $flag .= '請(qǐng)求數(shù):' . $sum . PHP_EOL;
  $flag .= '請(qǐng)求成功數(shù):' . $succeed . PHP_EOL;
  $flag .= '請(qǐng)求失敗數(shù):' . $fail . PHP_EOL;
  $flag .= $segment . PHP_EOL;
  return $flag;

}


/**
 * 發(fā)起秒殺請(qǐng)求
 */
function insertList( $urls, $logPath='' )
{
  $t = microtime(true);
  $result = model_thread_result_get($urls);
  $e = microtime(true);
  $timeDiff = $e-$t;
  echo "總執(zhí)行時(shí)間:" . $timeDiff . PHP_EOL;
  foreach( $result as $v ) {
   $msg = '用戶【' . $v['id'] . '】秒殺商品, 返回結(jié)果 ' . $v['result'] . ' 用時(shí)【' . $v['time'] . ' 秒】 當(dāng)前時(shí)間【'.$v['now'].'】';
   writeLog( $msg,$logPath );
  }
  $logStr = createLog( $result, $timeDiff);
  writeLog( $logStr, $logPath );
  return $result;
}


//發(fā)起秒殺請(qǐng)求
for ($i=0; $i  1000; $i++)
{
  $urls_array[] = array("name" => "baidu", "url" => "http://***.***.com/seckill/shopping/listinsert");
}

$list = insertList( $urls_array, './inset.log' );

//發(fā)起秒殺結(jié)果查詢請(qǐng)求
$urls_array = [];
foreach( $list as $v ) {
  if( $v['result'] === false ) {
   continue;
  }
  $urls_array[] = array(
        "name"  => "baidu",
        "url"  => "http://***.***.com/seckill/shopping/query",
        'user_id' => $v['id'],
  );
}
insertList( $urls_array, './query.log' );

測(cè)試代碼機(jī)器性能(開發(fā)機(jī)):

訂單代碼機(jī)器性能(測(cè)試機(jī)):

系統(tǒng)測(cè)試結(jié)果:

模擬 1000 并發(fā)的情況,單機(jī)每秒 300+ 訂單,服務(wù)器毫無壓力。
反倒是測(cè)試機(jī)受不了了,CPU 飆升 100%。 Apache 偶爾崩潰。

不知道是 PHP 多線程和 Windows 環(huán)境的支持不好,還是 PHP 多線程本身的問題,區(qū)區(qū) 1000 線程跑不動(dòng)。多線程的地方還是比較需要 Python 和 C 出馬。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

您可能感興趣的文章:
  • 淺談php使用curl模擬多線程發(fā)送請(qǐng)求
  • 實(shí)例講解php實(shí)現(xiàn)多線程
  • php使用curl_init()和curl_multi_init()多線程的速度比較詳解
  • PHP7多線程搭建教程
  • PHP中多線程的兩個(gè)實(shí)現(xiàn)方法
  • php與python實(shí)現(xiàn)的線程池多線程爬蟲功能示例
  • php多線程并發(fā)實(shí)現(xiàn)方法
  • php中foreach結(jié)合curl實(shí)現(xiàn)多線程的方法分析
  • 如何用PHP實(shí)現(xiàn)多線程編程

標(biāo)簽:白酒營(yíng)銷 興安盟 株洲 曲靖 濱州 太原 南昌 南京

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《PHP多線程模擬實(shí)現(xiàn)秒殺搶單》,本文關(guān)鍵詞  PHP,多,線程,模擬,實(shí)現(xiàn),秒殺,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《PHP多線程模擬實(shí)現(xiàn)秒殺搶單》相關(guān)的同類信息!
  • 本頁收集關(guān)于PHP多線程模擬實(shí)現(xiàn)秒殺搶單的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    营山县| 遂溪县| 石门县| 台北市| 万荣县| 承德县| 辽阳市| 深泽县| 理塘县| 丰都县| 泸溪县| 宝应县| 临桂县| 永济市| 县级市| 梨树县| 襄樊市| 东乡族自治县| 枝江市| 杭锦旗| 泊头市| 株洲县| 和田市| 静乐县| 高平市| 淮滨县| 杭州市| 抚远县| 青海省| 北碚区| 闽侯县| 永安市| 崇明县| 拜泉县| 汉源县| 洮南市| 清涧县| 沂源县| 皋兰县| 衢州市| 醴陵市|