본 콘텐츠는 사용자의 편의를 고려해 자동 기계 번역 서비스를 사용하였습니다. 영어 원문과 다른 오류, 누락 또는 해석상의 미묘한 차이가 포함될 수 있습니다. 필요하시다면 영어 원문을 참조하시기를 바랍니다.
Cloudflare의 Containers를 기반으로 Browser Run을 재구축하여 더 높은 사용량 제한, 더 빠른 성능, 더 나은 안정성을 제공합니다.
이제 Workers 바인딩을 통해 분당 60개의 브라우저를 스핀업하고 최대 120개의 브라우저를 동시에 실행할 수 있습니다. 이는 이전 제한의 4배입니다. 또한 Quick Action 응답 시간은 50% 이상 감소했습니다. 아무것도 변경할 필요가 없습니다. 이러한 개선 사항은 오늘부터 적용됩니다. 또한 이전보다 더 빠르게 수정 사항과 새로운 기능을 제공합니다. Cloudflare에서 이러한 작업을 수행한 방법과 데이터를 확인하려면 계속 읽어보세요.
Browser Run을 사용하면 개발자가 Cloudflare의 전역 네트워크에서 실행되는 헤드리스 브라우저 인스턴스를 프로그래밍 방식으로 제어하고 상호 작용할 수 있습니다. 이는 웹 애플리케이션의 엔드투엔드 테스트, 의심스러운 URL의 안전한 조사, 브라우저가 PDF 문서를 쉽게 렌더링하는 방법을 활용하는, 무엇보다도 스크린샷 캡처 및 콘텐츠 추출 등의 빠른 작업에 유용합니다. 최근에는 웹과 상호작용하는 것이 AI 에이전트의 중요한 원동력이 되었습니다. Cloudflare는 자동화된 브라우저를 대규모로 책임감 있게 활용하는 데 가장 적합한 플랫폼인 Browser Run을 구축하고 있습니다.
Cloudflare Containers를 채택하기 전에는 브라우저 격리 (BISO)와 인프라를 공유했습니다. 기술적으로는 비슷했지만, BISO의 더 큰 컨테이너 이미지 때문에 시작과 개발이 느려졌습니다. 결정적으로 BISO 브라우저에는 최적의 글로벌 배포가 부족하여 복원력과 대기 시간이 저하되었습니다. 또한 일반적인 BISO 사용자의 길고 안정적인 세션이 Browser Run의 짧고 급격한 사용량과 충돌하여 확장 병목 현상과 가용성 지연이 발생했습니다.
다행히도 Cloudflare에서는 많은 내부 개발 끝에 작년에 Durable Object(DO) 지원 Containers 오픈 베타를 출시했으며, 이는 궁극적으로 두 제품 플랫폼에 도움이 될 잠정 채택을 준비했다는 의미입니다. 대부분의 성공적인 제품 플랫폼과 마찬가지로, Cloudflare는 가능한 경우 자체 플랫폼을 기반으로 구축하여 외부 고객보다 먼저 고충 사항을 느끼고 해결할 수 있도록 최선을 다하고 있습니다.
우리는 BISO의 사용자와 함께 소수의 사용자에게 컨테이너 기반 브라우저를 제공하기 위해 들어오는 요청 경로에 Worker를 삽입하는 것으로 점진적인 마이그레이션을 시작했습니다. 개발 과정에서의 이러한 이중 지원이 핵심이었습니다. 이를 통해 성능을 비교하고, 구현 버그를 찾아내고, 궁극적으로 컨테이너 기반 접근 방식의 이점에 대한 확신을 가질 수 있었습니다.
속도를 높여가면서 먼저 모든 Quick Actions 엔드포인트에 Container 브라우저를 사용했고, 무료 계정에서 Workers 브라우저 바인딩을 통한 연결을 사용했고, 출시 전에 안정성을 검증하기 위해 종량제 계정을 사용했습니다. 나머지 모든 계약 고객에게 배포하므로, 고객은 조치를 취하거나 기존 작업자를 재배포할 필요가 없는 전환이 보장되었습니다.
하지만 Cloudflare의 입장에서는 시간대가 겹치는 시대에 걸쳐 문서가 간편하고, 관찰하기 쉬우며, 동료가 가벼워진 불안정한 초기 단계의 Containers 플랫폼 인터페이스에 익숙해지는 데 새로운 어려움을 겪었습니다. 하지만 고객 제로인 우리 팀에 피드백을 제공했기 때문에, 저희는 외부 고객에게도 이점을 제공하는 실질적인 업그레이드로 이어지는 촉박한 피드백 루프를 제공할 수 있었습니다. 그럼에도 불구하고 초기에는 극복해야 하는 마찰이 많았으며, 대부분의 경우 클로즈드 베타 버전을 통해 활발하게 개발될 것으로 예상되었습니다. 극복해야 할 다른 장애물이 새로운 기술 환경에 내재되어 있었습니다.
예를 들어 브라우저를 전 세계적으로 실행할 수 있게 되면 아키텍처도 적응해야 했습니다. DO 지원 컨테이너는 들어오는 요청에 최대한 가깝게 Durable Object를 생성하지만, 연결된 컨테이너가 지구 반대편에서 스핀업할 수도 있습니다. 이는 "내 앱을 시작"과 같은 원샷 메시지에는 잘 작동하지만, 메시지 사이에 WebSocket을 설정하여 스크린샷 요청을 위해 수십 개의 메시지를 교환하면 지구를 가로지르는 추가 밀리초가 합산되기 시작합니다.
Cloudflare의 솔루션은? 사전 예열된 DO 지원 브라우저 컨테이너의 지역적 풀을 생성하여 DO와 컨테이너 간의 최대 거리(및 최대 대기 시간)를 제한합니다. 요청이 들어오면 해당 지역 내에서 사용자와 가장 가까운 DO 컨테이너 쌍을 선택합니다. 이렇게 하면 사용자로의 DO 및 컨테이너로의 DO의 두 홉 모두에서 대기 시간이 낮게 유지됩니다. 전체 아키텍처에서 몇 가지 움직이는 부분을 더 추가하지만, 저희는 변화하는 수요에 따라 용량을 할당하고 재할당할 수 있도록 각 브라우저의 전역 상태를 관찰할 수 있는 한 그럴 만한 가치가 있다고 생각했습니다. 어느 정도까지는 Workers KV ...의 완벽한 사용 사례입니다.
작년 초부터 헤드리스 브라우저에 대한 수요가 증가하고 있습니다. 요약하면, AI 에이전트 빌더는 Browser Run을 발견하고 신속하게 기존 용량을 초과하는 요청량을 가져왔습니다. 우리는 확장 가능한 접근 방식으로 이러한 새로운 수요를 충족하기 위해 풀 용량을 신속하게 조정할 수 있다는 한계에 빠르게 도달했습니다. 약 30초에 달하는 KV의 최종 일관성이 주요 요청 경로에 병목 현상이 되고 있었습니다. KV를 확인하고 컨테이너가 "사용 가능" 상태로 표시되지만, 해당 컨테이너로 라우팅할 때(30초 후)에는 이미 클레임된 상태일 수 있습니다. 이러한 지연은 경쟁 조건과 브라우저 과도 할당을 유발하여 Cloudflare에서 수요 급증에 대응하기 위해 확장할 수 있는 속도가 심각하게 제한됩니다.
이전에는 각 컨테이너 상태를 KV에 저장했습니다. 즉, 캐시 TTL로 인해 1분 전 상태를 계속 가져올 수 있었습니다(최근 KV에서 최소 캐시 TTL을 30초로 변경했지만, 그럼에도 불구하고 이 값은 여전히 너무 높습니다).
우리는 대신 컨테이너 상태를 D1 인스턴스로 마이그레이션하기로 결정했습니다. D1의 트랜잭션 특성이 여기에 적합합니다. 우리가 사용자에게 브라우저를 할당하면, 브라우저는 독점적으로 사용자의 것입니다. 브라우저는 공유 리소스가 아닙니다. SQLite 트랜잭션은 원자 할당을 보장하고 두 요청이 동일한 브라우저를 동시에 차지할 수 있는 경쟁 조건을 방지합니다.
다음은 브라우저 획득 쿼리를 단순화한 버전입니다.
WITH candidate_pool AS (
-- candidate pool logic to pick based on latency and other rules
)
UPDATE containers
SET status = 'picked'
WHERE sessionId IN (
SELECT sessionId
FROM candidate_pool
ORDER BY RANDOM()
LIMIT ?5
)
RETURNING data
저희는 D1 샤드를 위치별로 보관하며, 수천 개의 컨테이너가 실행될 수 있고 각 컨테이너가 5초마다 상태를 업데이트해야 한다는 점을 고려할 때, 계속해서 문제가 발생했습니다. 바로 데이터베이스에 과부하가 걸리는 문제였습니다. 예를 들어, 각 쓰기에 1ms가 걸리는 경우, 우리는 최대 1,000번까지 쓸 수 있으며, 이는 쓰기당 하나의 행에 불과하므로 데이터베이스에 과부하가 걸리기 전에 컨테이너를 5,000개만 사용할 수 있다는 의미입니다.
그러나 이러한 쓰기를 일괄 처리하면 훨씬 더 높은 값을 얻을 수 있습니다. 일괄 쓰기가 개별 쓰기보다 크게 길지 않으므로 처리량을 수십 배까지 늘릴 수 있습니다. 저희 경우에는 100개의 행 배치를 사용하므로 이제 위치당 최대 500,000개의 컨테이너를 업데이트할 수 있습니다. 이 여유 공간은 용량 계획에서 더 이상 병목 현상이 발생하지 않음을 의미합니다.
현재 일괄 쓰기의 P95는 0.1ms입니다!
Cloudflare에서는 일괄 쓰기를 위해 각 컨테이너가 5초마다 자체 상태를 계산하여 위치 대기열에 추가하는 Queues를 사용합니다. 그런 다음 100 배치 크기 및 1초 배치 제한 시간 초과로 Worker 소비자를 구성합니다.
{
...
"queues": {
"consumers": [
{
"queue": "production-core-containers-queue-weur",
"max_batch_size": 100,
"max_batch_timeout": 1,
"max_retries": 1,
},
...
]
...
}
}
이 구성을 사용하면 2초 미만으로 허용 가능한 지연 시간을 달성할 수 있습니다. 하지만 대기열 백로그는 여전히 부실 상태를 초래할 수 있습니다. 이 경우 각 지역은 기본 대기열이 따라잡을 때까지 지정된 백업 지역으로 대체됩니다.
이제 전용 인프라를 통해 원치 않는 부작용이나 BISO 같은 다른 제품의 비대함 없이 브라우저 컨테이너 이미지를 업그레이드할 수 있었습니다. 이를 통해 스크린샷 및 콘텐츠 추출 등의 퀵 액션을 최적화할 수 있는 문이 열렸습니다. 이전에는 작업자가 원격 브라우저에 대해 WebSocket을 설정하고 한 번에 하나씩 지침을 전송했습니다. 즉, 페이지를 열고, 해당 URL로 이동한 다음, 페이지가 로드될 때까지 기다린 다음 스크린샷을 찍는 것입니다. 다음 단계를 시작하려면 먼저 각 단계를 완료해야 했습니다.
그러나 이제 단일 HTTP 요청의 모든 매개변수를 컨테이너에 직접 전송하면 전체 흐름이 작업자와 브라우저 간에 오가는 일 없이 내부적으로 실행됩니다.
퀵 액션 응답 시간의 평균이 급격히 감소했습니다. 사용자가 브라우저 세션에서 필요한 정보를 더 빠르게 얻을 수 있기 때문입니다. 브라우저가 준비될 때까지 기다리는 시간이 줄어들고 DevTools 프로토콜 메시지를 더 빠르게 처리할 수 있게 됩니다.
이러한 새로운 규모에서 실시간 상태 관리를 극복한다는 것은 최근 출시된 /crawl 엔드포인트 와 같은 새로운 기능을 발견하고 개발하는 데 더 많은 시간을 할애할 수 있다는 것을 의미했습니다.
또한, 공유 브라우저 격리 컨테이너를 남겨두고 또 다른 중요한 혜택을 누릴 수 있었습니다. 바로 업그레이드가 빨라졌습니다.
사용 중인 브라우저가 공유 제품 인프라에서 작동했을 때, Chrome을 업그레이드한다는 것은 자체 로드맵과 우선순위가 있는 여러 팀과 제품 간에 협력하는 것을 의미했습니다. 하지만 이제 자체 컨테이너 이미지를 실행했으므로 더 빠른 속도로 업그레이드할 수 있습니다. 예를 들어, 많은 요청을 받은 기능인 WebGL을 이제 새로운 에이전트 기반 상호작용 패턴을 가능하게 하는 WebMCP(모델 컨텍스트 프로토콜)와 함께 브라우저 기반 렌더링에 사용할 수 있습니다. 다른 Cloudflare 제품에서처럼 부작용 없이 브라우저 버전과 플래그를 제어할 수 있기 때문에 두 가지 모두가 가능합니다.
간단히 말해서, 우리는 특히 에이전트 개발을 위해 브라우저의 강력한 성능을 대규모로 활용하기 시작했습니다. 여러분도 참여하기를 바랍니다. Cloudflare 문서를 확인하세요.
Browser Run은 모든 Workers 요금제에서 사용할 수 있습니다. 빠른 시작 가이드로 시작하거나, 빠른 작업을 탐색하거나, /crawl 엔드포인트를 사용하여 사이트의 링크를 따라 모든 웹 페이지에서 데이터를 심층적으로 추출해 보세요.
AI 에이전트 구축? Browser Run 지원이 내장된 Cloudflare 에이전트 SDK를 확인해 보세요.