다음을 통해 공유

Azure App Service 접속 시 속도 저하 문의합니다.

CBIS 0 평판 포인트
2025-11-05T04:50:41.5733333+00:00

안녕하세요,

Azure App Service B2 인스턴스를 만들어 php 코드 기반의 웹 앱을 올려둔 상태입니다.

현재 php를 통해 온프레미스 서버에 POST로 쿼리를 보내고 결과를 웹페이지에 출력하고 있습니다.

그러나 간혹 메인 페이지를 열 때 속도 저하 문제가 생깁니다. (curl로 핑을 날려봤을 때 간혹 time out 에러가 뜨는 것을 확인할 수 있었습니다. 또한, 응답 시간을 메트릭으로 확인했을 때 현저하게 올라가는 것이 확인됩니다.)
혹시 이런 문제에 대해 알려진 문제가 있거나, 해결 화면 캡처 2025-11-05 134953

방안이 있을까요?

Azure App Service
Azure App Service

Azure App Service는 확장 가능하고 중요 업무용한 웹앱을 만들고 배포하는 데 사용되는 서비스입니다.

댓글 0개 설명 없음

답변 1개

정렬 기준: 가장 유용함
  1. 익명
    2025-11-14T23:11:52.8966667+00:00

    Hi @CBIS ,

    Microsoft Q&A에 질문을 올려 주셔서 감사합니다. 제가 영어에서 귀하의 언어로 번역했기 때문에 문법적 오류가 있을 수 있는 점 양해해 주세요.

    증상과 메트릭에서 보신 응답 시간 급증을 알려주셔서 감사합니다. “Response Time”의 갑작스러운 상승과 가끔 발생하는 cURL 타임아웃은 Azure App Service 앱이 동일한 온프레미스 서버로 자주 아웃바운드 호출을 보낼 때 흔히 발생하는 문제입니다. 많은 경우 느려짐은 App Service 자체에서 발생하는 것이 아니라 온프레미스 쪽의 일시적인 네트워크 제한, 혼잡 또는 지연 때문에 발생합니다.

    아래에는 Linux App Service(B2 요금제)에서 실행되는 PHP 앱을 대상으로 문제를 진단하고 해결하는 간단한 단계별 설명을 적어 두었습니다.

    가장 흔한 근본 원인:

    1. App Service의 SNAT 포트 소진 문제 Azure App Service는 각 인스턴스마다 사용할 수 있는 아웃바운드 SNAT 포트 수가 제한되어 있습니다. PHP 앱이 동일한 온프레미스 서버로 짧은 연결을 매우 자주 생성하면, 이 포트들이 일시적으로 가득 찰 수 있습니다. 그렇게 되면 온프레미스 시스템에는 문제가 없어도 응답 지연, 임의의 타임아웃, “연결할 수 없음” 등의 오류가 발생할 수 있습니다. 이를 완화하려면 다음을 적용할 수 있습니다:

    연결 재사용(keep-alive) 활성화 커넥션 풀링 사용 VNet Integration + NAT Gateway로 아웃바운드 용량 확장

    1. 온프레미스 연결 경로에서의 추가 지연 App Service가 온프레미스 서버에 공용 인터넷 또는 Hybrid Connections를 통해 연결하는 경우, 지연과 변동성이 자연스럽게 증가합니다. Hybrid Connections는 연결 가능성 확보에는 좋지만, 중간에 릴레이 홉이 하나 더 생기기 때문에 VPN 또는 ExpressRoute 같은 사설 연결보다 성능이 떨어질 수 있습니다.
    2. 콜드 스타트 또는 백그라운드 프로세스 재시작 App Service Plan에서 Always On 옵션이 활성화되어 있는지 확인하세요(기본 요금제 이상에서 지원). 이를 활성화하지 않으면 PHP/Nginx 컨테이너가 일정 시간 후 유휴 상태가 되어, 다시 깨울 때 로드 시간이 더 길어지는 현상이 발생할 수 있습니다.
    3. 애플리케이션 수준 문제(PHP / Nginx / 쿼리 동작) 비효율적인 요청, 재시도 로직 부족, keep-alive 미사용, 오래 걸리는 쿼리 등이 있으면 애플리케이션이 느려지고 위 문제들이 더 크게 드러날 수 있습니다. Microsoft는 요청 시간과 의존성(Dependency) 호출 시간을 비교하여 지연이 어디에서 발생하는지 파악할 것을 권장합니다.

    지금 바로 확인해야 할 사항 (10–15분 내 점검)

    1. “Always On”이 활성화되어 있는지 확인 포털 > App Service > Configuration > General settings로 이동하여 Always On = On으로 설정하세요. B2 요금제에서는 이 기능을 사용할 수 있습니다. 이를 켜두면 PHP/Nginx 컨테이너가 항상 활성 상태를 유지하여 첫 요청이 느려지는 문제를 방지할 수 있습니다.
    2. SNAT 관련 문제 점검 포털 > App Service > Diagnose and solve problems로 이동한 후 Networking Diagnostics에서 “SNAT”를 검색하세요. 아웃바운드 연결 실패가 많거나 SNAT 사용량이 한계에 다다른 기록이 보이면, 아웃바운드 포트가 부족해지고 있다는 의미입니다. Microsoft 문서에는 이러한 현상의 전형적인 징후와 해결책이 정리되어 있습니다.
    3. 실제로 시간이 소비되는 지점 파악 Application Insights(또는 기타 APM 도구)를 사용해 **Request duration(요청 시간)**과 **Dependency(HTTP) duration(외부 호출 시간)**을 비교하세요. 대부분의 시간이 온프레미스 엔드포인트로의 Dependency 호출에서 소비된다면, 느려지는 원인은 PHP 코드가 아니라 아웃바운드 네트워크 연결 문제입니다.
    4. 온프레미스 환경 점검 온프레 방화벽/NAT, TLS 엔드포인트, 서버 리소스 상태가 정상인지 확인하세요. Hybrid Connections를 사용 중이라면 Hybrid Connection Manager(HCM)가 정상 실행 중이며 실제 백엔드 서비스와 물리적으로 가까운 위치에 있는지 확인해야 합니다. Hybrid Connections는 릴레이 홉이 추가되므로 자연스럽게 지연이 늘어날 수 있다는 점을 기억하세요.

    빠르게 효과를 볼 수 있는 해결 방법

    A. PHP에서 연결 재사용 및 cURL 최적화(불필요한 새 소켓 생성 방지)

    HTTP/1.1 keep-alive를 반드시 활성화하세요. 이렇게 하면 매번 새로운 TCP/TLS 연결을 만드는 대신 기존 연결을 재사용할 수 있어 성능이 크게 향상됩니다.

    적절한 타임아웃 설정 및 지수 백오프(exponential backoff)를 적용한 재시도 로직을 추가하세요. 일시적인 실패가 있을 때 바로 오류로 처리하는 대신, 짧은 간격을 두고 재시도하면 안정성이 높아집니다.

    동일한 호스트/포트로 동시에 발생하는 신규 연결 수를 줄이도록 설계하세요. 이는 SNAT 포트 소진을 방지하고 지연 시간을 낮추는 데 매우 효과적입니다.

    <?php
    function post_with_retry($url, $payload, $headers = [], $tries = 3)
    {
        $ch = curl_init($url);
        // Keep-Alive (HTTP/1.1) + reuse connection
        curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
        curl_setopt($ch, CURLOPT_TCP_KEEPALIVE, 1);
        curl_setopt($ch, CURLOPT_TCP_KEEPIDLE, 30);
        curl_setopt($ch, CURLOPT_TCP_KEEPINTVL, 10);
    
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array_merge($headers, [
            'Connection: keep-alive'
        ]));
    
        // Timeouts: connect vs. total
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);  // seconds
        curl_setopt($ch, CURLOPT_TIMEOUT, 20);        // seconds
    
        // Follow redirects if your on-prem API issues 302s
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_MAXREDIRS, 2);
    
        // Optional: capture timing for diagnostics
        curl_setopt($ch, CURLINFO_HEADER_OUT, true);
        $attempt = 0;
        $backoffMs = 250;
    
        do {
            $attempt++;
            $response = curl_exec($ch);
            $errno    = curl_errno($ch);
    
            if ($errno === 0 && $response !== false) {
                break;
            }
            // Retry on transient network errors/timeouts
            usleep($backoffMs * 1000);
            $backoffMs = min($backoffMs * 2, 2000);
        } while ($attempt < $tries);
    
        $info = curl_getinfo($ch); // contains timing, primary_ip, etc.
        curl_close($ch);
    
        return [$response, $info, $errno];
    }
    

    이 접근 방식은 **“요청 1개당 연결 1개”라는 비효율적 패턴(=SNAT 소진을 매우 빠르게 유발하는 안티패턴)**을 줄여 주며, 부하 상황에서도 지연 시간을 안정적으로 유지하는 데 도움이 됩니다. Microsoft의 SNAT 가이드라인에서도 포트 소진을 피하기 위해 커넥션 풀링 및 연결 재사용을 명확하게 권장하고 있습니다.

    B. App Service를 스케일 아웃 또는 스케일 업하기

    스케일 아웃(인스턴스 수 증가) 인스턴스를 늘리면 인스턴스마다 고유한 SNAT 포트 풀을 가지므로, 전체 사용 가능한 SNAT 포트 수가 증가합니다. 이는 온프레미스 서버로 향하는 총 아웃바운드 용량을 확장하는 효과가 있습니다.

    트래픽이 순간적으로 몰리는 경우 Autoscale(자동 확장)을 사용하면 급격한 요청 폭주를 완화하는 데 도움이 됩니다.

    단, 연결 재사용(keep-alive/connection pooling)을 반드시 구현해야 합니다. 스케일링만으로는 “새 연결을 너무 자주 여는 문제”를 해결할 수 없습니다.

    C. Hybrid Connections를 사용하는 경우

    Hybrid Connection Manager(HCM)를 백엔드 서버와 같은 LAN에 최대한 가깝게 위치시키세요. 이는 지연을 줄이는 데 매우 중요합니다.

    가능하다면 Azure Relay와 App Service를 동일한 Azure 지역(region)에 배치하여 왕복 지연을 최소화하세요.

    Hybrid Connections는 구조적으로 모든 트래픽이 릴레이를 거쳐 이동하므로 자연스러운 오버헤드가 존재합니다. 따라서 VPN/ExpressRoute 같은 직접적인 사설 네트워크보다 약간 느린 성능이 나올 수 있으며, 이에 맞춰 테스트하는 것이 좋습니다.

    Reference:

    https://learn.microsoft.com/en-us/azure/app-service/troubleshoot-intermittent-outbound-connection-errors

    https://learn.microsoft.com/en-us/azure/app-service/overview-nat-gateway-integration

    https://learn.microsoft.com/en-us/azure/app-service/app-service-hybrid-connections?tabs=windows

    https://learn.microsoft.com/en-us/azure/app-service/configure-language-php?pivots=platform-linux

    위의 내용이 도움이 되었는지 알려주시거나, 이 문제에 대해 추가적인 도움이 필요하시면 언제든지 말씀해 주세요.

    제공된 정보가 도움이 되었다면 "업보트(upvote)" 부탁드립니다. 이는 저희뿐 아니라 같은 문제를 겪는 다른 사용자들에게도 큰 도움이 됩니다.

    이 대답이 도움이 되었나요?

    댓글 0개 설명 없음

답변

질문 작성자는 답변을 '승인됨'으로 표시하고, 중재자는 답변을 '추천됨'으로 표시할 수 있습니다. 이를 통해 사용자는 해당 답변이 작성자의 문제를 해결했다는 것을 알 수 있습니다.