Rumah pembangunan bahagian belakang tutorial php PHP多线程模拟实现秒杀抢单活动(附代码)

PHP多线程模拟实现秒杀抢单活动(附代码)

May 19, 2018 am 10:05 AM
php kod Aktiviti

这次给大家带来PHP多线程模拟实现秒杀抢单活动(附代码),PHP多线程模拟实现秒杀抢单活动的注意事项有哪些,下面就是实战案例,一起来看一下。

先说秒杀模块的思路:

正常情况下的用户秒杀操作

1、发起秒杀请求
2、进入秒杀队列
3、随机滞后 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' );
Salin selepas log masuk

测试代码机器性能(开发机):

订单代码机器性能(测试机):

系统测试结果:

模拟 1000 并发的情况,单机每秒 300+ 订单,服务器毫无压力。
反倒是测试机受不了了,CPU 飙升 100%。 Apache 偶尔崩溃。

不知道是 PHP 多线程和 Windows 环境的支持不好,还是 PHP 多线程本身的问题,区区 1000 线程跑不动。多线程的地方还是比较需要 Python 和 C 出马。

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

redis计数器类使用步骤详解

php处理抢购类高并发请求实现详解

Atas ialah kandungan terperinci PHP多线程模拟实现秒杀抢单活动(附代码). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Panduan Pemasangan dan Naik Taraf PHP 8.4 untuk Ubuntu dan Debian Panduan Pemasangan dan Naik Taraf PHP 8.4 untuk Ubuntu dan Debian Dec 24, 2024 pm 04:42 PM

PHP 8.4 membawa beberapa ciri baharu, peningkatan keselamatan dan peningkatan prestasi dengan jumlah penamatan dan penyingkiran ciri yang sihat. Panduan ini menerangkan cara memasang PHP 8.4 atau naik taraf kepada PHP 8.4 pada Ubuntu, Debian, atau terbitan mereka

7 Fungsi PHP Saya Menyesal Saya Tidak Tahu Sebelum ini 7 Fungsi PHP Saya Menyesal Saya Tidak Tahu Sebelum ini Nov 13, 2024 am 09:42 AM

Jika anda seorang pembangun PHP yang berpengalaman, anda mungkin merasakan bahawa anda telah berada di sana dan telah melakukannya. Anda telah membangunkan sejumlah besar aplikasi, menyahpenyahpepijat berjuta-juta baris kod dan mengubah suai sekumpulan skrip untuk mencapai op

Cara Menyediakan Kod Visual Studio (Kod VS) untuk Pembangunan PHP Cara Menyediakan Kod Visual Studio (Kod VS) untuk Pembangunan PHP Dec 20, 2024 am 11:31 AM

Kod Visual Studio, juga dikenali sebagai Kod VS, ialah editor kod sumber percuma — atau persekitaran pembangunan bersepadu (IDE) — tersedia untuk semua sistem pengendalian utama. Dengan koleksi sambungan yang besar untuk banyak bahasa pengaturcaraan, Kod VS boleh menjadi c

Jelaskan JSON Web Tokens (JWT) dan kes penggunaannya dalam PHP API. Jelaskan JSON Web Tokens (JWT) dan kes penggunaannya dalam PHP API. Apr 05, 2025 am 12:04 AM

JWT adalah standard terbuka berdasarkan JSON, yang digunakan untuk menghantar maklumat secara selamat antara pihak, terutamanya untuk pengesahan identiti dan pertukaran maklumat. 1. JWT terdiri daripada tiga bahagian: header, muatan dan tandatangan. 2. Prinsip kerja JWT termasuk tiga langkah: menjana JWT, mengesahkan JWT dan muatan parsing. 3. Apabila menggunakan JWT untuk pengesahan di PHP, JWT boleh dijana dan disahkan, dan peranan pengguna dan maklumat kebenaran boleh dimasukkan dalam penggunaan lanjutan. 4. Kesilapan umum termasuk kegagalan pengesahan tandatangan, tamat tempoh, dan muatan besar. Kemahiran penyahpepijatan termasuk menggunakan alat debugging dan pembalakan. 5. Pengoptimuman prestasi dan amalan terbaik termasuk menggunakan algoritma tandatangan yang sesuai, menetapkan tempoh kesahihan dengan munasabah,

Bagaimana anda menghuraikan dan memproses HTML/XML dalam PHP? Bagaimana anda menghuraikan dan memproses HTML/XML dalam PHP? Feb 07, 2025 am 11:57 AM

Tutorial ini menunjukkan cara memproses dokumen XML dengan cekap menggunakan PHP. XML (bahasa markup extensible) adalah bahasa markup berasaskan teks yang serba boleh yang direka untuk pembacaan manusia dan parsing mesin. Ia biasanya digunakan untuk penyimpanan data

Program PHP untuk mengira vokal dalam rentetan Program PHP untuk mengira vokal dalam rentetan Feb 07, 2025 pm 12:12 PM

Rentetan adalah urutan aksara, termasuk huruf, nombor, dan simbol. Tutorial ini akan mempelajari cara mengira bilangan vokal dalam rentetan yang diberikan dalam PHP menggunakan kaedah yang berbeza. Vokal dalam bahasa Inggeris adalah a, e, i, o, u, dan mereka boleh menjadi huruf besar atau huruf kecil. Apa itu vokal? Vokal adalah watak abjad yang mewakili sebutan tertentu. Terdapat lima vokal dalam bahasa Inggeris, termasuk huruf besar dan huruf kecil: a, e, i, o, u Contoh 1 Input: String = "TutorialSpoint" Output: 6 menjelaskan Vokal dalam rentetan "TutorialSpoint" adalah u, o, i, a, o, i. Terdapat 6 yuan sebanyak 6

Terangkan pengikatan statik lewat dalam php (statik: :). Terangkan pengikatan statik lewat dalam php (statik: :). Apr 03, 2025 am 12:04 AM

Mengikat statik (statik: :) Melaksanakan pengikatan statik lewat (LSB) dalam PHP, yang membolehkan kelas panggilan dirujuk dalam konteks statik dan bukannya menentukan kelas. 1) Proses parsing dilakukan pada masa runtime, 2) Cari kelas panggilan dalam hubungan warisan, 3) ia boleh membawa overhead prestasi.

Apakah kaedah Magic PHP (__construct, __destruct, __call, __get, __set, dll) dan menyediakan kes penggunaan? Apakah kaedah Magic PHP (__construct, __destruct, __call, __get, __set, dll) dan menyediakan kes penggunaan? Apr 03, 2025 am 12:03 AM

Apakah kaedah sihir PHP? Kaedah sihir PHP termasuk: 1. \ _ \ _ Membina, digunakan untuk memulakan objek; 2. \ _ \ _ Destruct, digunakan untuk membersihkan sumber; 3. \ _ \ _ Call, mengendalikan panggilan kaedah yang tidak wujud; 4. \ _ \ _ Mendapatkan, melaksanakan akses atribut dinamik; 5. \ _ \ _ Set, melaksanakan tetapan atribut dinamik. Kaedah ini secara automatik dipanggil dalam situasi tertentu, meningkatkan fleksibiliti dan kecekapan kod.

See all articles