国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 語言 > PHP > 正文

PHP多線程模擬實現秒殺搶單

2024-05-05 00:02:16
字體:
來源:轉載
供稿:網友

應集團要求給服務號做了個搶單秒殺的功能,需要對秒殺做個測試,想試試PHP多線程,就模擬了下搶單功能。

先說秒殺模塊的思路:

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

1、發起秒殺請求
2、進入秒殺隊列
3、隨機滯后 1 - 2 秒進行秒殺結果查詢請求(算是變相分流吧)
4、成功則生成訂單
5、返回結果

以下是模擬秒殺的代碼:

<?phpset_time_limit(0);/*** 線程的執行任務*/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),     ];   }  }}/*** 執行多線程*/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;}/*** 發送 HTTP 請求*/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 .= '總共執行時間:' . $timeDiff . PHP_EOL ;  $flag .= '最大執行時間:' . $maxTime . PHP_EOL;  $flag .= '最小執行時間:' . $minTime . PHP_EOL;  $flag .= '平均請求時間:' . $avgTime . PHP_EOL;  $flag .= '請求數:' . $sum . PHP_EOL;  $flag .= '請求成功數:' . $succeed . PHP_EOL;  $flag .= '請求失敗數:' . $fail . PHP_EOL;  $flag .= $segment . PHP_EOL;  return $flag;}/** * 發起秒殺請求 */function insertList( $urls, $logPath='' ){  $t = microtime(true);  $result = model_thread_result_get($urls);  $e = microtime(true);  $timeDiff = $e-$t;  echo "總執行時間:" . $timeDiff . PHP_EOL;  foreach( $result as $v ) {   $msg = '用戶【' . $v['id'] . '】秒殺商品, 返回結果 ' . $v['result'] . ' 用時【' . $v['time'] . ' 秒】 當前時間【'.$v['now'].'】';   writeLog( $msg,$logPath );  }  $logStr = createLog( $result, $timeDiff);  writeLog( $logStr, $logPath );  return $result;}//發起秒殺請求for ($i=0; $i < 1000; $i++){  $urls_array[] = array("name" => "baidu", "url" => "http://***.***.com/seckill/shopping/listinsert");}$list = insertList( $urls_array, './inset.log' );//發起秒殺結果查詢請求$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' );

測試代碼機器性能(開發機):

PHP,多線程,秒殺,搶單,PHP秒殺搶單,PHP搶單

訂單代碼機器性能(測試機):

PHP,多線程,秒殺,搶單,PHP秒殺搶單,PHP搶單

系統測試結果:

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

不知道是 PHP 多線程和 Windows 環境的支持不好,還是 PHP 多線程本身的問題,區區 1000 線程跑不動。多線程的地方還是比較需要 Python 和 C 出馬。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到PHP教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 油尖旺区| 蓬安县| 晋州市| 射阳县| 鹤岗市| 四川省| 金塔县| 山阳县| 潞城市| 扶风县| 墨玉县| 丽江市| 台北市| 肇州县| 渭南市| 花莲市| 静乐县| 珠海市| 富川| 定边县| 翁牛特旗| 云龙县| 南木林县| 岳普湖县| 宁武县| 墨玉县| 九寨沟县| 景东| 雅江县| 新郑市| 太和县| 穆棱市| 达孜县| 万盛区| 邵阳市| 福建省| 仙桃市| 南江县| 永年县| 东宁县| 宣武区|