플러그인 권장사항

이 페이지에서는 올바르고, 성능이 우수하며, 격리가 잘 된 서비스 확장 프로그램 플러그인을 작성하는 방법을 설명합니다. 제한된 API 노출 영역이 있는 제한된 엔진 샌드박스에서 플러그인이 실행되므로 정확성이 중요합니다. 플러그인은 최종 사용자 요청 중에 소량의 리소스로 실행되므로 성능이 중요합니다. 격리는 프로젝트 수준에서 제공됩니다.

시작하기

샘플에서 시작

시작하려면 플러그인 코드 샘플을 살펴보세요. 경로 또는 쿼리 파싱, 헤더 재작성, 맞춤 로깅, 맞춤 인증과 같은 일반적인 플러그인 패턴의 예입니다.

지원되는 API 사용

플러그인은 Proxy-Wasm 바이너리 인터페이스 (ABI)에 대해 컴파일해야 합니다. 서비스 확장 프로그램은 HTTP 헤더 및 본문 변이, 로컬 응답, 맞춤 로깅, 플러그인 구성을 포함하는 프록시-Wasm ABI의 하위 집합을 지원합니다. Proxy-Wasm은 로깅을 위한 stdoutstderr, clock_time_get, random_get을 비롯한 WASI 미리보기 1의 작은 하위 집합도 지원합니다.

서비스 확장 프로그램은 타이머, 맞춤 측정항목, 공유 데이터, 공유 대기열 또는 아웃바운드 네트워크 호출을 지원하지 않습니다. 또한 서비스 확장 프로그램은 요청 처리를 일시중지하려고 하는 플러그인 콜백 반환 값을 지원하지 않으며 이를 무시합니다.

기능 테스트 및 벤치마크 실행

정확성과 성능을 평가하기 위해 플러그인을 실행하고 테스트하고 벤치마킹할 수 있는 로컬 플러그인 테스터 도구를 제공합니다. Docker 컨테이너에서 이 도구를 호출하여 플러그인 바이너리와 입력 및 기대치의 텍스트 프로토를 전달합니다. 로컬 테스터 문서테스트 입력 예시를 참고하세요.

정확성

시계에 의존하지 마세요

보안상의 이유로 시계 시간은 컨텍스트 생성 시 (플러그인 또는 요청의 경우) 설정되며 플러그인 호출 중에 고정된 상태로 유지됩니다. 즉, WebAssembly 플러그인은 절전 모드로 전환되면 안 됩니다. 시간이 지나지 않으므로 절전 모드가 시간 초과됩니다. 또한 플러그인이 자체 실행 시간을 측정할 수 없다는 의미이기도 합니다. 이 정보는 Cloud Monitoring에서 확인할 수 있습니다.

헤더 이름을 대소문자를 구분하지 않는 것으로 처리

HTTP 시맨틱스에 따라 HTTP 헤더 필드 이름은 대소문자를 구분하지 않는 것으로 처리해야 합니다. 플러그인에서 작성한 헤더 대소문자는 클라이언트나 백엔드로 전송되기 전에 변경될 수 있습니다.

성능

플러그인 비정상 종료 방지

플러그인이 비정상 종료되면 트리거 요청에 오류가 표시됩니다. 이 문제가 자주 발생하면 플러그인 다시 시작이 제한되어 여러 사용자에게 영향을 미치는 오류가 발생합니다.

플러그인 비정상 종료를 방지하려면 다음을 시도해 보세요.

  • 모든 종류의 단정은 피하세요. 대신 오류 로깅 또는 사용자에게 전송되는 로컬 응답을 구성하세요.
  • Rust에서는 패닉을 일으킬 수 있는 unwrap와 같은 메서드를 사용하지 마세요. 또한 panic::set_hook를 사용하여 비정상 종료를 처리하도록 플러그인을 구성할 수 있습니다.
  • Google에서 제공하는 플러그인 테스터를 사용하여 플러그인을 테스트하고 형식이 잘못되었거나 비어 있는 입력이 플러그인 비정상 종료 없이 처리되는지 확인합니다.

실행 속도를 위해 컴파일

빌드 옵션 -O3 (C++의 경우) 또는 opt-level=3 (Rust의 경우)를 사용하여 WebAssembly 코드를 컴파일하여 최적의 실행 속도를 달성하세요.

정규 표현식 사전 컴파일

요청별 경로 (HTTP 핸들러)에서 컴퓨팅 집약적인 작업을 피하세요. 대신 플러그인 구성 시 요청과 관련이 없는 작업을 실행하고 사전 계산된 상태를 각 HTTP 요청 컨텍스트 (스트림 컨텍스트라고도 함)에 전달하세요.

특히 플러그인 구성 시간에 정규 표현식을 사전 컴파일하세요. 정규식 코드 샘플은 이를 달성하는 방법을 보여줍니다.

HTTP 컨텍스트에 데이터 복사 방지

루트 컨텍스트와 HTTP 컨텍스트 간에 데이터를 공유할 때는 비용이 많이 드는 복사 또는 클론 호출을 피하세요. 대신 포인터나 참조를 공유하세요. C++에서는 루트 컨텍스트가 HTTP 컨텍스트보다 오래 지속되므로 std::shared_ptr 또는 원시 포인터와 참조를 사용하여 이를 수행할 수 있습니다. Rust에서는 std::rc::Rc를 사용하여 값을 공유할 수 있습니다. Go에서는 가비지 컬렉터에 의해 삭제되는 값에 대한 포인터를 저장하여 값을 공유할 수 있습니다.

보안

프로젝트별로 워크로드 격리

Google 인프라에서 동일한 Google Cloud 프로젝트가 소유한 플러그인은 동일한 보안 샌드박스에서 실행될 수 있습니다. 즉, WebAssembly 런타임은 동일한 프로젝트의 플러그인 간에 유일한 보안 장벽입니다.

보안 분리가 필요한 워크로드에 별도의 Google Cloud 프로젝트를 사용합니다. 이 방법을 사용하면 리소스와 권한도 분리할 수 있습니다.

Media CDN의 보안 비밀 제한

Media CDN은 Google의 물리적 제어 범위 외에서 운영되는 하드웨어 풀에서 실행되도록 설계되었습니다. Media CDN용 보안 관련 플러그인을 작성할 때는 전용 호스트 이름이나 하위 도메인을 사용하고 자주 순환되는 서명 키로 플러그인을 구성하세요.