PHP multi-thread simulation to achieve second-kill and ticket grabbing, php multi-thread Simulation
According to the requirements of the group, the service number is offered a single flash sales function. You need to test the flash sales function. If you want to try PHP multithreading, you can simulate the single-flash sales function.
Let's talk about the second kill module:
Normal user seckilling operations
1. Initiate a second kill request
2. Enter the second kill queue
3. Random latency 1-2 seconds for second-kill result query requests (in disguise)
4. An order is generated if the request is successful.
5. Return results
The following code simulates the second kill:
<? Phpset_time_limit (0);/*** Thread execution task */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, 'right' => microtime (true),] ;}} /*** execute multiple threads */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 ;} /*** send HTTP Request */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, expires, 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 ;} /*** friendly print variable * @ param $ val */function dump ($ val) {echo '<pre>'; var_dump ($ val ); echo '</pre>';}/*** write log * @ 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);}/*** generate log information * @ 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. = 'total execution time :'. $ timeDiff. PHP_EOL; $ flag. = 'maximum execution time :'. $ maxTime. PHP_EOL; $ flag. = 'minimum execution time :'. $ minTime. PHP_EOL; $ flag. = 'average request time :'. $ avgTime. PHP_EOL; $ flag. = 'requests :'. $ sum. PHP_EOL; $ flag. = 'number of successful requests :'. $ succeed. PHP_EOL; $ flag. = 'number of request failures :'. $ fail. PHP_EOL; $ flag. = $ segment. PHP_EOL; return $ flag;}/*** initiate a second kill Request */function insertList ($ urls, $ logPath = '') {$ t = microtime (true ); $ result = model_thread_result_get ($ urls); $ e = microtime (true); $ timeDiff = $ e-$ t; echo "total execution time :". $ timeDiff. PHP_EOL; foreach ($ result as $ v) {$ msg = 'user 【'. $ v ['id']. '] seckill product, return result '. $ v ['result']. 'time 【'. $ v ['time']. 'Second] current time 【'. $ v ['now ']. ']'; writeLog ($ msg, $ logPath) ;}$ logStr = createLog ($ result, $ timeDiff); writeLog ($ logStr, $ logPath); return $ result ;} // initiate a second kill request for ($ I = 0; $ I <1000; $ I ++) {$ urls_array [] = array ("name" => "baidu ", "url" => "http ://***. ***. com/seckill/shopping/listinsert ");} $ list = insertList ($ urls_array ,'. /inset. log'); // initiate a second kill result query request $ 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 ');
Test code machine performance (developer ):
Order code machine performance (Test Machine ):
System test results:
The simulation of 1000 concurrency, a single machine more than 300 orders per second, the server is no pressure.
On the other hand, the test machine cannot handle it, and the CPU usage soared by 100%. Apache occasionally crashes.
I don't know whether the support for PHP multithreading is poor in the Windows environment, or the problem of PHP multithreading itself. The 1000 threads in the zone cannot run. For multithreading, Python and C are required.
The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.