현재 위치: > 최신 기사 목록> Curl_Close가 대규모 동시 요청에서 메모리를 실제로 최적화 할 수 있습니까? 이 세부 사항을 간과했을 수도 있습니다

Curl_Close가 대규모 동시 요청에서 메모리를 실제로 최적화 할 수 있습니까? 이 세부 사항을 간과했을 수도 있습니다

gitbox 2025-05-18

CURL은 네트워크 요청에 PHP를 사용할 때 가장 일반적인 도구 중 하나입니다. 특히 배치 풀기 API 인터페이스 데이터, 푸시 알림, 여러 주소 확인 등과 같은 대규모 동시성 시나리오에서 CURL 이 종종 첫 번째 선택입니다. 그리고 이러한 관행에서 종종 논의되는 질문은 다음과 같습니다.

이것은 작은 세부 사항처럼 들리지만 동시 동시 시나리오에서는이 세부 사항이 프로그램이 안정적으로 실행될 수 있는지에 대한 열쇠가 될 수 있습니다.

1. curl_close 란 무엇입니까?

curl_close ($ ch) 는 ​​php에서 curl_init () 에 의해 초기화 된 핸들 을 닫는 함수입니다. 간단히 말해서 관련 리소스를 공개합니다. 많은 튜토리얼과 문서는 다음과 같이 강조 할 것입니다. "사용 후 닫으십시오."

그러나 대규모 동시 요청에서 자주 자주 전환하는 자원 전환은 실제로 더 효율적이라는 것을 의미합니까?

2. 메모리 릴리스 ≠ 메모리 복구

많은 개발자들은 Curl_Close () 호출되는 한 메모리가 즉시 시스템으로 "해제"될 것이라고 잘못 생각하지만 그렇지 않습니다. PHP에서, 특히 긴 연결 스크립트 또는 Swoole/FPM Resident Memory의 경우 PHP의 메모리 관리 메커니즘은 메모리를 즉시 운영 체제로 반환하지는 않지만이를 "사용 가능한"것으로 표시하고 다음에 기다릴 것입니다.

즉, 스크립트에 수백 또는 수천 개의 CURL 요청이있는 경우 매번 Curl_Close ()를 호출하더라도 메모리 사용량이 계속 증가 할 수 있습니다. 특히 요청이 많은 양의 데이터를 반환하는 경우.

3. 실제 비교 테스트

다음은 설명하기위한 간단한 비교 테스트입니다.

 // 장면 1:호출되지 않았습니다 curl_close
for ($i = 0; $i < 1000; $i++) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, "https://api.gitbox.net/test-endpoint?id=$i");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($ch);
    // 소홀히 하다 curl_close
}

// 장면 2:부르다 curl_close
for ($i = 0; $i < 1000; $i++) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, "https://api.gitbox.net/test-endpoint?id=$i");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($ch);
    curl_close($ch);
}

Memory_get_usage () 의 비교를 통해 단일 실행 스크립트에서 두 개의 쓰기 방법은 메모리 사용에 거의 차이가 없으며 차이도 무시할 수 있음이 밝혀졌습니다.

그러나 FPM을 처리 하에서 오랫동안 실행되는 서비스에서 여러 요청 또는 Swoole Coroutines를 처리하면 Curl_Close ()를 호출하지 않으면 메모리의 지속적인 백 로그가 발생하여 결국 OOM 또는 성능 병목 현상을 유발합니다.

4. 동시성에 더 좋은 방법이 있습니까?

동시 요청의 수가 클 경우 curl_multi를 사용하는 것이 올바른 솔루션입니다. 이를 통해 여러 동시 요청을 동시에 초기화 할 수 있으며 프로세스는 폴링 메커니즘을 통해 비동기 적으로 반환하여 효율성을 향상시키고 리소스 릴리스를 더 잘 제어합니다.

 $multiHandle = curl_multi_init();
$curlHandles = [];

for ($i = 0; $i < 100; $i++) {
    $ch = curl_init("https://api.gitbox.net/batch?id=$i");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_multi_add_handle($multiHandle, $ch);
    $curlHandles[$i] = $ch;
}

// 동시 요청을 수행하십시오
do {
    $status = curl_multi_exec($multiHandle, $active);
    curl_multi_select($multiHandle);
} while ($active);

// 결과를 얻고 가까이
foreach ($curlHandles as $ch) {
    $response = curl_multi_getcontent($ch);
    curl_multi_remove_handle($multiHandle, $ch);
    curl_close($ch);
}

curl_multi_close($multiHandle);

5. Curl_Close는 "도움이 될 수 없지만" "책임"이어야합니다.

결론은 다음과 같습니다. curl_close () 자체는 특히 단기간 스크립트에서 메모리를 크게 최적화 할 수 없습니다. 그러나 동시성, 상주 메모리 및 긴 수명주기 서비스에서 Curl_Close ()를 호출하지 않는 것은 심각한 자원 누출로 결국 서비스 안정성을 줄입니다.

따라서 성능 최적화의 "비밀"은 아니지만 프로그램이 "실행할 수있는"전제입니다.

작은 제안

  • 일반 배치 스크립트 : Curl + Curl_Close가 권장됩니다

  • 높은 동시성 처리 : Curl_multi를 사용하거나 Coroutine 클라이언트를 사용하십시오 (예 : Guzzle + Async)

  • 긴 연결 서비스 : Curl_Close를 포함한 자원 수명주기를 관리하십시오.

  • PHP FPM : 스크립트에서 요청의 메모리 사용에주의를 기울이고 요청을 합리적으로 분할하거나 요청 볼륨을 제어합니다.

세부 사항에 직면 한 경우에만 성능이 바위만큼 안정적 일 수 있습니다. 다음에 동시 요청을 작성하면 Curl_Close ()를 잊어 버린 경우 뒤돌아 보면서도 볼 수도 있습니다.