>  기사  >  백엔드 개발  >  깜짝 세일 및 주문 접수 활동을 구현하기 위한 PHP 멀티스레드 시뮬레이션(코드 포함)

깜짝 세일 및 주문 접수 활동을 구현하기 위한 PHP 멀티스레드 시뮬레이션(코드 포함)

php中世界最好的语言
php中世界最好的语言원래의
2018-05-19 10:05:073210검색

이번에는 반짝 세일 및 주문 잡기 활동을 구현하기 위한 PHP 멀티 스레드 시뮬레이션(코드 포함)을 가져왔습니다. 플래시 판매 및 주문 잡기 활동을 구현하기 위한 PHP 멀티 스레드 시뮬레이션의 주의 사항은 무엇입니까? 사례를 살펴보겠습니다.

플래시 세일 모듈의 아이디어에 대해 먼저 이야기해 보겠습니다.

일반적인 상황에서 사용자 플래시 세일 작업

1. 플래시 세일 요청 시작
2. 플래시 세일 결과를 만듭니다. 1~2초의 무작위 지연으로 쿼리 요청(위장된 전환으로 간주될 수 있음)
4. 성공하면 주문이 생성됩니다.
5. 결과 반환

다음은 플래시 세일을 시뮬레이션하는 코드입니다. :

<?php
set_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 class="brush:php;toolbar:false">';
  var_dump($val);
  echo '
'; } /**  * 写日志  * @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' );테스트 코드 머신 성능(개발 머신):

주문 코드 머신 성능(테스트 머신):

시스템 테스트 결과:

시뮬레이트된 1000 동시성 상황, 초당 300개 이상의 주문 단일 머신으로 서버에 부담을 주지 않습니다.

반대로 테스트 머신이 이를 견디지 ​​못하고 CPU가 100% 급등했습니다. Apache가 때때로 충돌합니다.

PHP 멀티스레딩과 Windows 환경이 잘 지원하지 않아서인지, 아니면 PHP 멀티스레딩 자체의 문제인지는 모르겠습니다. 멀티스레딩에는 여전히 Python과 C가 필요합니다.

이 기사의 사례를 읽은 후 방법을 마스터했다고 생각합니다. 더 흥미로운 정보를 보려면 PHP 중국어 웹사이트의 다른 관련 기사를 주목하세요!

추천 도서:

redis 카운터 클래스를 사용하는 단계에 대한 자세한 설명

PHP의 긴급 구매 클래스에서 높은 동시성 요청 구현에 대한 자세한 설명

위 내용은 깜짝 세일 및 주문 접수 활동을 구현하기 위한 PHP 멀티스레드 시뮬레이션(코드 포함)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.