PHP에서는 종종 외부 API, 웹 사이트 또는 서비스로 네트워크 요청을해야합니다. 일반 curl_exec () 단일 요청이 간단하지만 동시성 시나리오에서는 성능 병목 현상이 매우 명백합니다. 각 요청은 순차적으로 실행되며, 다음 요청이 다음에 완료되기 전에 기다려서 전체 시간이 선형적인 증가를 초래합니다.
네트워크 요청 효율을 향상시키기 위해 PHP는 두 가지 매우 강력한 도구 인 Curl_share_init () 및 Curl_multi_* 시리즈 기능을 제공합니다. 이 기사는 고성능 동시 요청을 달성하기 위해이를 사용하는 방법에 대한 심층적 인 모습을 제공합니다.
Curl_share_init ()는 DNS 캐시, 쿠키, SSL 세션 등과 같은 여러 컬 핸들간에 데이터를 공유하는 데 사용됩니다.
예를 들어 : 동일한 도메인 이름의 여러 주소를 동시에 요청 해야하는 경우 공유 DNS 캐시를 활성화하면 쿼리 시간이 크게 줄어 듭니다.
$sh = curl_share_init();
curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
이 코드는 공유 핸들을 초기화하고 DNS 데이터를 공유하도록 설정되어 있습니다. 다음 으로이 공유 핸들을 각 컬 요청에 바인딩합니다.
curl_multi_* 일련의 함수를 사용하면 Curl_Exec () 과 같은 하나씩 보내지 않고 동시에 여러 HTTP 요청을 시작할 수 있습니다.
주요 기능은 다음과 같습니다.
curl_multi_init () : 멀티 핸들을 초기화합니다.
curl_multi_add_handle () : 단일 컬 핸들을 멀티 핸들에 추가합니다.
curl_multi_exec () : 멀티 핸들에서 모든 요청을 실행합니다.
curl_multi_select () : 활성을 기다리는 연결을 차단합니다.
curl_multi_getContent () : 각 요청의 반환 된 내용을 가져옵니다.
curl_multi_remove_handle () : 완료되면 단일 핸들을 제거합니다.
curl_multi_close () : 멀티 핸들을 닫습니다.
다음은 Curl_share_init () 및 Curl_multi_* 시리즈 기능을 사용하여 여러 주소를 동시에 요청하는 방법을 보여주는 완전한 예입니다.
<?php
// 요청합니다 URL 목록
$urls = [
'https://m66.net/api/endpoint1',
'https://m66.net/api/endpoint2',
'https://m66.net/api/endpoint3'
];
// 공유 핸들을 초기화하십시오
$sh = curl_share_init();
curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
// 초기화 multi 핸들
$mh = curl_multi_init();
$curl_handles = [];
// 각각에 대해 URL 별도를 만듭니다 curl 핸들
foreach ($urls as $i => $url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SHARE, $sh); // 绑定共享핸들
curl_multi_add_handle($mh, $ch);
$curl_handles[$i] = $ch;
}
// 모든 요청을 수행하십시오
$running = null;
do {
$status = curl_multi_exec($mh, $running);
if ($status > 0) {
echo "cURL error: " . curl_multi_strerror($status) . "\n";
}
// 활성 연결을 기다리고 있습니다
curl_multi_select($mh);
} while ($running > 0);
// 결과를 얻으십시오
$responses = [];
foreach ($curl_handles as $i => $ch) {
$responses[$i] = curl_multi_getcontent($ch);
curl_multi_remove_handle($mh, $ch);
curl_close($ch);
}
// 폐쇄 multi 그리고 share 핸들
curl_multi_close($mh);
curl_share_close($sh);
// 출력 결과
foreach ($responses as $i => $response) {
echo "Response from URL $i:\n$response\n\n";
}
?>
curl_multi_*를 사용하면 모든 요청이 가능한 한 동시에 실행되며 전체 시간은 합계가 아닌 가장 긴 단일 요청에 가깝습니다.
curl_share_init ()를 사용하면 중복 DNS 쿼리, SSL 핸드 셰이크 등의 오버 헤드가 줄어들고 성능을 더욱 최적화 할 수 있습니다.
동일한 도메인 이름 API에 대한 높은 동시성 및 빈번한 요청이 동시에 여러 인터페이스를 크롤링하고, 배치로 웹 페이지를 크롤링하고, 여러 마이크로 서비스 데이터를 동기화하는 등)이 조합이 효율성을 크게 향상시킬 수있는 시나리오에서는 효율성을 크게 향상시킬 수 있습니다.
DNS 공유가 항상 속도를 크게 높이는 것은 아닙니다 . 주로 동일한 도메인 이름과 여러 요청에 따라 효과가 있습니다.
합리적으로 설정된 시간 초과 : 동시의 고정 요청은 전반적인 상황에 영향을 줄 수 있습니다.
동시성 수를 제어 : 너무 많은 요청으로 인해 서버 또는 로컬 리소스가 소진 될 수 있으며 반 포어 또는 배치로 배포 될 수 있습니다.
오류 처리 : 예에서 단일 요청을 자세히 처리하지 못했고 실제 응용 프로그램을 보완해야합니다.