현재 위치: > 최신 기사 목록> 높은 동시성 환경에서 socket_set_block의 위험과 응답

높은 동시성 환경에서 socket_set_block의 위험과 응답

gitbox 2025-05-26

1. Socket_set_Block 및 높은 동시성 위험의 작동 원리

Socket_set_block 소켓이 차단 모드로 설정된 후 IO 작업 (예 : Socket_read , Socket_write )이 데이터를 읽거나 쓰기가 성공할 때까지 현재 프로세스 또는 스레드가 차단됩니다. 이는 단일 스레드 또는 일회성이 낮은 시나리오에서 매우 간단하고 효과적이지만, 높은 일환 시나리오에서는 위험이 다음과 같은 점에 주로 반영됩니다.

  1. 막힘은 자원 직업을 유발합니다 <br> 차단 모드는 특히 네트워크가 지연되거나 피어가 천천히 응답 할 때 요청을 잠시 실행할 수없는 요청을 처리 할 수있게 해줄 것입니다. 프로세스는 IO 단계에서 "고정"되어 많은 수의 프로세스가 대기 및 리소스를 차지하게됩니다.

  2. 처리량 감소, 응답 대기 시간 증가 <br> 많은 연결이 차단되면 서버는 정시에 새 연결 요청을 처리 할 수 ​​없으므로 응답 시간이 길고 사용자 경험이 더 나빠질 수 있습니다.

  3. 스레드/프로세스의 수는 제한되어 있습니다 <br> 서버의 동시성 기능은 사용 가능한 스레드 또는 프로세스의 수에 의해 제한됩니다. 차단 작업을 사용하면 이러한 스레드 또는 프로세스를 대기 상태로 만들어 스레드 풀이 소진되기가 매우 쉽습니다.

  4. 교착 상태 위험 <br> 차단 및 대기 중에 상호 배타적 인 자원에 대한 경쟁이 관여하는 경우 교착 상태를 일으키고 프로그램이 발생하기 쉽습니다.


2. 높은 동시성 환경에서 일반적인 대처 전략

1. 비 블로킹 모드 Socket_set_nonBlock을 사용하십시오

Socket_set_nonblock을 호출하여 소켓을 비 블로킹 모드로 설정하면 IO 작업은 현재 프로세스를 차단하지 않지만 즉시 돌아갑니다. 이벤트 중심 메커니즘 (예 : PHP 확장의 Select , Poll 또는 Libevent )과 결합하면 동시 처리 기능을 효과적으로 향상시킬 수 있습니다.

 <?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, '0.0.0.0', 8080);
socket_listen($socket);

socket_set_nonblock($socket);

while (true) {
    $client = @socket_accept($socket);
    if ($client === false) {
        // 새로운 연결이 없습니다,루프를 계속하십시오
        usleep(10000); // 휴식을 취하십시오,줄이다CPU점유
        continue;
    }

    // 고객에게 socket 또한 비 블로킹을 설정합니다
    socket_set_nonblock($client);

    // 데이터를 읽거나 쓸 때,결합 socket_select 청취 상태
}
?>

2. Socket_Select를 사용하여 멀티플렉싱을 달성하십시오

Socket_select는 여러 소켓의 읽기 및 쓰기 상태를 듣고 단일 연결을 차단하지 않으며 서버의 효율성을 개선하여 여러 연결을 처리 할 수 ​​있습니다.

 <?php
$read = [$socket];
$write = null;
$except = null;

if (socket_select($read, $write, $except, 0, 200000)) {
    foreach ($read as $readSocket) {
        if ($readSocket === $socket) {
            $client = socket_accept($socket);
            socket_set_nonblock($client);
            // 듣기 위해 추가하십시오
        } else {
            $data = socket_read($readSocket, 1024);
            if ($data === false || $data === '') {
                socket_close($readSocket);
                // 목록 목록에서 제거하십시오
            } else {
                // 처리 데이터
            }
        }
    }
}
?>

3. 비동기 IO 또는 이벤트 중심 프레임 워크를 사용하십시오

Swoole 및 ReactPHP와 같은 비동기 프레임 워크의 도움으로 차단을 완전히 피할 수 있으며 많은 동시 연결을 비동기식으로 처리하여 성능을 크게 향상시킬 수 있습니다.

 <?php
use Swoole\Coroutine\Http\Server;

$server = new Server("0.0.0.0", 9501);

$server->handle('/', function ($request, $response) {
    $response->end("Hello, Swoole!");
});

$server->start();
?>

4. 스레드 또는 프로세스 풀링 기술

메인 스레드의 차단을 피하기 위해 독립 작업자 스레드 또는 프로세스에 차단 작업을 할당하기 위해 다중 프로세스 또는 멀티 스레딩을 합리적으로 사용하십시오.


3. 요약

위험 포인트 응답 조치
차단하면 프로세스가 리소스 사용을 기다릴 수 있습니다 비 블로킹 모드 또는 이벤트 드라이버를 사용하십시오
응답 대기 시간 및 처리량 드롭 Socket_Select를 사용하여 여러 연결을 듣습니다
스레드 풀이 소진되었습니다 멀티 스레드/다중 프로세스 풀을 사용하여 응력을 공유하십시오
교착 상태 위험 상호 배타적 교착 상태를 피하기 위해 합리적인 자원 액세스 전략을 설계하십시오.

동시 동시 환경에서 차단 소켓을 사용하지 않고 비 차단, 이벤트 중심 모델 및 비동기 프레임 워크를 합리적으로 사용하여 PHP 프로그램의 효율적이고 안정적인 작동을 보장하십시오.