PHP 동시 다발 장면 의 세 가지 솔 루 션 코드 인 스 턴 스

6765 단어 PHP높 은 병발
초 살,사재 기 등 동시 다발 장면 에서 초 매 현상 이 나타 날 수 있 습 니 다.PHP 언어 에서 원생 이 동시 다발 적 인 해결 방안 을 제공 하지 않 았 기 때문에 다른 방식 으로 병행 통 제 를 실현 해 야 합 니 다.사실은 방안 이 여러 가지 가 있 습 니 다.오늘 은 밤 을 들 어 벽돌 을 던 져 옥 을 끌 어 올 리 는 것 일 뿐 다른 더 좋 은 방안 이 있 으 면 직접 놀 러 가면 됩 니 다.
흔히 볼 수 있 는 세 가지 해결 방안 을 보 여 줍 니 다.
대기 열 을 사용 하면 프로 세 스 처리 대기 열 을 추가 로 만 들 고 병렬 요청 은 모두 대기 열 에 넣 습 니 다.추가 프로 세 스 직렬 로 처리 하면 병렬 문 제 는 존재 하지 않 습 니 다.그러나 추가 프로 세 스 지원 과 처리 지연 이 심각 합 니 다.본 고 는 먼저 이런 방법 을 토론 하지 않 습 니 다.
데이터베이스 트 랜 잭 션 특징 을 이용 하여 원자 업 데 이 트 를 하려 면 데이터 뱅 크 의 트 랜 잭 션 특성 에 의존 해 야 합 니 다.
파일 의 자 물 쇠 를 빌려 다음 요청 을 처리 할 때 플 로 크 로 파일 을 잠 그 고 자 물 쇠 를 성공 적 으로 가 져 와 야 주문 서 를 처리 할 수 있 습 니 다.
1.Redis 트 랜 잭 션 특징 활용
redis 사 무 는 원자 작업 으로 주문 처리 과정 에서 데이터 가 다른 병행 프로 세 스 에 의 해 수정 되 지 않 았 음 을 보증 할 수 있 습 니 다.
예제 코드:

<?php
$http = new swoole_http_server("0.0.0.0", 9509); //    9509
$http->set(array(
 'reactor_num' => 2, //reactor thread num
 'worker_num' => 4 //worker process num
));
$http->on('request', function (swoole_http_request $request, swoole_http_response $response) {
 $uniqid = uniqid('uid-', TRUE); //       ID
 $redis = new Redis();
 $redis->connect('127.0.0.1', 6379); //    redis
 $redis->watch('rest_count'); //    rest_count           
 $rest_count = intval($redis->get("rest_count")); //       ID
 if ($rest_count > 0){
 $value = "{$rest_count}-{$uniqid}"; //       ,        
 // do something ...                        
 $rand = rand(100, 1000000);
 $sum = 0;
 for ($i = 0; $i < $rand; $i++) {$sum += $i;}
 // redis   
 $redis->multi();
 $redis->lPush('uniqids', $value);
 $redis->decr('rest_count');
 $replies = $redis->exec(); //      redis   
 //    rest_count              ,       
 if (!$replies) {
 echo "   {$value}   " . PHP_EOL;
 }
 }
 $redis->unwatch();
});
$http->start();
ab 테스트 사용

$ ab -t 20 -c 10 http://192.168.1.104:9509/
2.파일 을 이용 하여 다른 자 물 쇠 를 배열 합 니 다(차단 모드)
차단 모드 에서 프로 세 스 가 파일 의 자 물 쇠 를 가 져 올 때 다른 프로 세 스 가 자 물 쇠 를 차지 하고 있다 면 이 프로 세 스 는 다른 프로 세 스 가 자 물 쇠 를 풀 때 까지 기다 리 고 자 물 쇠 를 가 져 온 후에 아래로 실행 합 니 다.
예제 코드:

<?php
$http = new swoole_http_server("0.0.0.0", 9510);
$http->set(array(
 'reactor_num' => 2, //reactor thread num
 'worker_num' => 4 //worker process num
));
$http->on('request', function (swoole_http_request $request, swoole_http_response $response) {
 $uniqid = uniqid('uid-', TRUE);
 $redis = new Redis();
 $redis->connect('127.0.0.1', 6379);
 $fp = fopen("lock.txt", "w+");
 //   (  )  ,        (     )
 if (flock($fp,LOCK_EX)) { //      
 //       ,      
 $rest_count = intval($redis->get("rest_count"));
 $value = "{$rest_count}-{$uniqid}";
 if ($rest_count > 0) {
 // do something ...
 $rand = rand(100, 1000000);
 $sum = 0;
 for ($i = 0; $i < $rand; $i++) {$sum += $i;}
 $redis->lPush('uniqids', $value);
 $redis->decr('rest_count');
 }
 //        ,    
 flock($fp, LOCK_UN);
 }
 fclose($fp);
});
$http->start();
ab 테스트 사용

$ ab -t 20 -c 10 http://192.168.1.104:9510/
3.파일 을 이용 하여 잠 금(비 차단 모드)
비 차단 모드 에서 프로 세 스 가 파일 배타 자 물 쇠 를 가 져 올 때 다른 프로 세 스 가 자 물 쇠 를 차지 하고 있다 면 이 프로 세 스 는 바로 자 물 쇠 를 가 져 오 는 데 실 패 했 음 을 판단 하고 계속 아래로 실 행 됩 니 다.\
예제 코드:

<?php
$http = new swoole_http_server("0.0.0.0", 9511);
$http->set(array(
 'reactor_num' => 2, //reactor thread num
 'worker_num' => 4 //worker process num
));
$http->on('request', function (swoole_http_request $request, swoole_http_response $response) {
 $uniqid = uniqid('uid-', TRUE);
 $redis = new Redis();
 $redis->connect('127.0.0.1', 6379);
 $fp = fopen("lock.txt", "w+");
 //      ,       flock()       ,   lock    LOCK_NB
 if(flock($fp,LOCK_EX | LOCK_NB)) //      
 {
 //       ,      
 $rest_count = intval($redis->get("rest_count"));
 $value = "{$rest_count}-{$uniqid}";
 if($rest_count > 0){
 // do something ...
 $rand = rand(100, 1000000);
 $sum=0;
 for ($i=0;$i<$rand;$i++){ $sum+=$i; }
 $redis->lPush('uniqids', $value);
 $redis->decr('rest_count');
 }
 //        ,    
 flock($fp,LOCK_UN);
 } else {
 //        ,        
 echo "{$uniqid} -     ,     ".PHP_EOL;
 }
 fclose($fp);
});
$http->start();
ab 테스트 사용

$ ab -t 20 -c 10 http://192.168.1.104:9511/
마지막 으로 세 가지 처리 방식 의 테스트 결 과 를 비교 해 보 겠 습 니 다.
redis 트 랜 잭 션 방식:

Concurrency Level:  10
Time taken for tests: 20.005 seconds
Complete requests:  17537
Failed requests:  0
Total transferred:  2578380 bytes
HTML transferred:  0 bytes
Requests per second: 876.62 [#/sec] (mean)
Time per request:  11.407 [ms] (mean)
Time per request:  1.141 [ms] (mean, across all concurrent requests)
Transfer rate:   125.86 [Kbytes/sec] received
파일 배타 잠 금(차단 모드):

Concurrency Level:  10
Time taken for tests: 20.003 seconds
Complete requests:  8205
Failed requests:  0
Total transferred:  1206282 bytes
HTML transferred:  0 bytes
Requests per second: 410.19 [#/sec] (mean)
Time per request:  24.379 [ms] (mean)
Time per request:  2.438 [ms] (mean, across all concurrent requests)
Transfer rate:   58.89 [Kbytes/sec] received
파일 배타 잠 금(비 차단 모드):

Concurrency Level:  10
Time taken for tests: 20.002 seconds
Complete requests:  8616
Failed requests:  0
Total transferred:  1266846 bytes
HTML transferred:  0 bytes
Requests per second: 430.77 [#/sec] (mean)
Time per request:  23.214 [ms] (mean)
Time per request:  2.321 [ms] (mean, across all concurrent requests)
Transfer rate:   61.85 [Kbytes/sec] received
테스트 결과 에 비해 redis 트 랜 잭 션 방식 은 파일 배타 적 잠 금 방식 보다 좋 고 파일 배타 적 잠 금 방식 에 서 는 차단 모드 가 차단 모드 보다 좋 습 니 다.
여기 서 PHP 동시 다발 장면 에 관 한 세 가지 솔 루 션 코드 인 스 턴 스 에 관 한 글 을 소개 합 니 다.더 많은 PHP 동시 다발 장면 과 관련 된 세 가지 솔 루 션 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 십시오.앞으로 많은 응원 바 랍 니 다!

좋은 웹페이지 즐겨찾기