플래시 세일, 급매 등의 동시 시나리오에서는 과매도가 발생할 수 있습니다. 따라서 PHP 언어에는 기본 동시성 솔루션이 없습니다. 동시성 제어를 달성하려면 필요합니다.
나열된 일반적인 솔루션은 다음과 같습니다.
- 큐를 사용하고, 큐를 처리하기 위해 추가 프로세스를 시작하고, 모든 동시 요청을 queue. 추가 프로세스에 의해 순차적으로 처리되는 경우 동시성 문제는 존재하지 않지만 추가 프로세스 지원과 심각한 처리 지연이 필요합니다. 이 기사에서는 이 방법에 대해 먼저 설명하지 않습니다.
- 데이터베이스의 트랜잭션 특성을 사용하여 원자성 업데이트를 수행합니다. 이 방법은 데이터베이스의 트랜잭션 특성에 의존합니다.
- 파일 단독 잠금 기능을 사용하면 주문 요청 처리 시 Flock을 사용하여 파일 잠금을 성공적으로 수행한 사람만 주문을 처리할 수 있습니다.
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 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 lPush('uniqids', $value); $redis->decr('rest_count'); } // 订单处理完成后,再释放锁 flock($fp, LOCK_UN); } fclose($fp); }); $http->start();
ab test 사용
$ 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;$ilPush('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 튜토리얼
컬럼을 방문하여 알아보세요!위 내용은 PHP 동시성 시나리오에 대한 여러 솔루션의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!
성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사
어 ass 신 크리드 그림자 : 조개 수수께끼 솔루션
1 몇 달 전ByDDD
Windows 11 KB5054979의 새로운 기능 및 업데이트 문제를 해결하는 방법
3 몇 주 전ByDDD
Atomfall에서 크레인 제어 키 카드를 찾을 수 있습니다
1 몇 달 전ByDDD
KB5055523을 수정하는 방법 Windows 11에 설치되지 않습니까?
2 몇 주 전ByDDD
Inzoi : 학교 및 대학에 지원하는 방법
3 몇 주 전ByDDD

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

ZendStudio 13.5.1 맥
강력한 PHP 통합 개발 환경

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

SublimeText3 Linux 새 버전
SublimeText3 Linux 최신 버전
