Python 2 런타임 환경

App Engine에서는 Python 프로그래밍 언어를 사용하여 웹 애플리케이션을 빌드할 수 있으며, 전문 개발자가 세계 최고 수준의 웹 애플리케이션을 빌드할 수 있는 다양한 Python용 라이브러리, 도구, 프레임워크를 활용할 수 있습니다. Python 애플리케이션은 Google의 확장 가능한 인프라에서 실행되며 대규모 영구 저장소 및 서비스를 사용합니다.

소개

App Engine은 안전한 '샌드박스' 환경에서 사전 로드된 Python 인터프리터를 사용하여 Python 애플리케이션 코드를 실행합니다. 앱은 이 환경과 상호작용하면서 웹 요청을 수신하고, 작업을 수행하고, 응답을 전송합니다.

Python 웹 앱은 WSGI 프로토콜을 사용하여 App Engine 웹 서버와 상호작용하기 때문에 앱은 WSGI와 호환되는 모든 웹 애플리케이션 프레임워크를 사용할 수 있습니다. 쉽게 시작할 수 있도록 webapp2라는 간단한 웹 애플리케이션 프레임워크가 App Engine에 포함되어 있습니다. 보다 대용량 애플리케이션의 경우 Django 같은 완성된 타사 프레임워크가 App Engine에서 원활하게 작동합니다.

Python 인터프리터는 사용자가 애플리케이션에 포함한 Python 모듈과 Python 표준 라이브러리를 비롯하여 모든 Python 코드를 실행할 수 있습니다. 인터프리터는 C 코드가 있는 Python 모듈을 로드할 수 없습니다. '순수' Python 환경이기 때문입니다.

안전한 '샌드박스' 환경은 서비스 및 보안을 위해 애플리케이션을 격리합니다. 앱이 다른 앱의 성능 및 확장성을 방해하지 않는 작업만 수행할 수 있도록 합니다. 예를 들어 앱은 로컬 파일 시스템에 데이터를 기록하거나 네트워크에 임의로 연결할 수 없습니다. 대신 앱은 App Engine이 제공하는 확장 가능한 서비스를 사용하여 데이터를 저장하고 인터넷을 통해 통신합니다. Python 인터프리터는 앱이 샌드박스 제한 내에서 작동하지 않는 것으로 알려진 표준 라이브러리로부터 Python 모듈을 가져오려고 시도할 때 예외를 발생시킵니다.

App Engine 플랫폼은 코드로 호출할 수 있는 다양한 서비스를 제공합니다. 애플리케이션에서 지정된 간격으로 실행되는 예약된 작업을 구성할 수도 있습니다.

Python 2 런타임 선택

App Engine에 애플리케이션을 배포하는 데 사용되는 app.yaml 구성 파일에 Python 런타임 환경을 지정합니다. 예를 들어 Python 버전 2.7을 사용하려면 app.yaml 파일에 다음을 추가합니다.

runtime: python27
api_version: 1
threadsafe: true
...

첫 번째 요소인 runtime은 Python 런타임 환경을 선택합니다.

두 번째 요소인 api_version은 사용할 Python 런타임 환경 버전을 선택합니다. 본 문서 작성 시점을 기준으로 App Engine에는 한 가지 버전의 Python 환경, 즉 버전 1만 있습니다. App Engine팀이 기존 코드와 호환되지 않을 수 있는 환경에 대한 변경사항을 릴리스해야 하는 경우 새 버전 식별자를 사용하여 이 작업을 수행합니다. 사용자가 api_version 설정을 변경하고 앱을 업로드하기 전까지 앱에서는 계속해서 선택된 버전을 사용합니다.

app.yaml 파일 및 App Engine에 앱을 배포하는 방법은 app.yaml 참조, Python 2.7로 마이그레이션, Python 앱 배포를 참조하세요.

샌드박스

App Engine이 애플리케이션에 대한 요청을 여러 웹 서버로 분산하도록 허용하고 애플리케이션 간에 간섭이 발생하지 않도록 하기 위해 애플리케이션은 제한된 '샌드박스' 환경에서 실행됩니다. 이 환경에서 애플리케이션은 코드를 실행하고, Datastore에 데이터를 저장하고, 쿼리하고, App Engine 메일, URL 가져오기, 사용자 서비스를 사용하며, 사용자의 웹 요청을 검토하고 응답을 준비할 수 있습니다.

App Engine 애플리케이션은 다음을 수행할 수 없습니다.

  • 파일 시스템에 쓰기. 애플리케이션은 Datastore를 사용하여 영구 데이터를 저장해야 합니다. 파일 시스템에서 읽는 것은 허용되며 애플리케이션과 함께 업로드된 모든 애플리케이션 파일을 사용할 수 있습니다.

  • 늦은 응답. 애플리케이션에 대한 웹 요청은 몇 초 이내에 처리되어야 합니다. 응답에 매우 오랜 시간이 걸리는 프로세스는 웹 서버의 과부하를 방지하기 위해 종료됩니다.

  • 기타 유형의 시스템 호출

Python에서 샌드박스 생성

Python 2.7 런타임을 사용하면 .pyc 파일을 업로드하고 사용할 수 있지만 이 파일의 .py.pyc 버전은 업로드할 수 없습니다. .py 또는 .pyc 파일(또는 조합)이 포함된 .zip 파일은 업로드할 수 있습니다. .pyc 파일을 업로드하는 경우 몇 가지 중요한 주의사항이 적용됩니다.

  • CGI 스크립트의 경우 스크립트 핸들러.pyc 파일을 업로드하는 경우에도 .py 파일 확장자를 계속 사용해야 합니다.
  • 기본적으로 배포 중에는 .pyc 파일을 건너뜁니다. 새 값으로 인해 .pyc 파일을 건너뛰지 않도록 app.yaml 파일의 skip_files 요소를 재정의해야 합니다.
  • Python 2.7을 사용하여 .pyc 파일을 빌드해야 합니다. 개발 머신에 Python 2.6과 같은 다른 버전의 Python이 있으면 2.7 버전을 구해 호환되는 .pyc 파일에 빌드해야 합니다.

순수 Python 2

Python 런타임 환경의 모든 코드는 순수 Python이어야 하며 C 확장 프로그램 또는 컴파일해야 하는 기타 코드를 포함할 수 없습니다.

환경에는 Python 표준 라이브러리가 포함됩니다. 핵심 기능이 App Engine에서 지원되지 않는 네트워킹 및 파일 시스템에 쓰기 등인 일부 모듈은 사용 중지되었습니다. os 모듈도 사용할 수 있지만 지원되지 않는 기능은 사용 중지되었습니다. 지원되지 않는 모듈을 가져오거나 지원되지 않는 기능을 사용하려고 하면 예외가 발생합니다.

App Engine과 작동하도록 표준 라이브러리의 일부 모듈이 교체되거나 맞춤설정되었습니다. 아래에 설명되어 있는 것처럼 해당하는 모듈은 두 Python 런타임에서 다릅니다.

Python 버전 2.7에서 맞춤설정된 라이브러리

Python 버전 2.7 런타임에서 다음 모듈이 교체되었거나 맞춤설정되었습니다.

  • StringIO로 별칭이 지정된 TemporaryFile을 제외한 tempfile은 사용 중지되었습니다.

  • 로깅을 사용할 수 있으며 적극적으로 권장됩니다. 로깅을 참조하세요.

Python 버전 2.7 런타임에는 Python 표준 라이브러리 및 App Engine 라이브러리 외에도 여러 타사 라이브러리가 포함되어 있습니다.

타사 Python 라이브러리 추가

애플리케이션 디렉터리에 코드를 넣어 타사 Python 라이브러리를 애플리케이션에 포함시킬 수 있습니다. 애플리케이션 디렉터리에 라이브러리 디렉터리에 대한 기호화된 링크를 만들면 이 링크를 따라 App Engine에 배포하는 앱에 해당 라이브러리가 포함됩니다.

Python 모듈의 포함 경로에는 app.yaml 파일이 포함된 디렉터리인 애플리케이션의 루트 디렉터리가 포함됩니다. 애플리케이션의 루트 디렉터리에서 생성한 Python 모듈은 이 루트의 경로를 통해 사용할 수 있습니다. Python이 하위 디렉터리를 패키지로 인식할 수 있도록 하위 디렉터리에 필요한 __init__.py 파일을 만들어야 합니다. 또한 라이브러리에 C 확장 프로그램이 필요하지 않는지 확인하세요.

스레드

스레드는 thread 또는 threading 모듈을 사용하여 Python 버전 2.7에서 생성할 수 있습니다. 스레드는 요청이 끝날 때 런타임에서 조인되므로 요청이 끝난 후에 스레드가 실행될 수는 없습니다.

백그라운드 스레드

수동 또는 기본 확장 인스턴스에서 실행되는 코드는 스레드 생성 요청보다 오래 지속되는 백그라운드 스레드를 시작할 수 있습니다. 그러면 인스턴스가 임의의 정기 작업 또는 예약된 작업을 수행하거나 요청이 사용자에게 반환된 후에도 백그라운드에서 계속 작업할 수 있습니다.

백그라운드 스레드의 os.environ 및 로깅 항목은 생성 스레드 항목과 독립적입니다.

App Engine용 SDK에서 google.appengine.api.background_thread 모듈을 가져와야 합니다.

from google.appengine.api import background_thread

BackgroundThread 클래스는 일반 Python threading.Threadclass와 같지만 클래스 생성 요청보다 '오래 지속'됩니다. start_new_background_thread() 함수는 백그라운드 스레드를 만들고 시작합니다.

# sample function to run in a background thread
def change_val(arg):
    global val
    val = arg

if auto:
    # Start the new thread in one command
    background_thread.start_new_background_thread(change_val, ['Cat'])
else:
    # create a new thread and start it
    t = background_thread.BackgroundThread(
        target=change_val, args=['Cat'])
    t.start()
App Engine API에서 생성되는 동시 백그라운드 스레드의 최대 개수는 인스턴스별로 10개입니다. (이 한도는 App Engine API와 관련되지 않은 일반 자바 스레드에 적용되지 않습니다.)

도구

App Engine용 SDK에는 애플리케이션 테스트, 애플리케이션 파일 업로드, Datastore 색인 관리, 로그 데이터 다운로드, 대용량 데이터를 Datastore에 업로드하기 위한 도구가 포함됩니다.

개발 서버는 로컬 컴퓨터에서 애플리케이션을 실행하여 애플리케이션을 테스트합니다. 이 서버는 Datastore 서비스와 샌드박스 제한을 시뮬레이션합니다. 또한 개발 서버는 테스트 중에 앱이 수행하는 쿼리를 기반으로 Datastore 색인의 구성을 생성할 수 있습니다.

gcloud 도구는 App Engine에서 실행되는 애플리케이션과의 모든 명령줄 상호작용을 처리합니다. gcloud app deploy를 사용하여 애플리케이션을 App Engine에 업로드하거나 Datastore 색인 구성과 같은 개별 구성 파일을 업데이트하여 코드를 배포하기 전에 새 색인을 빌드할 수 있습니다. 또한 앱의 로그 데이터를 확인하여 원하는 도구로 앱의 성능을 분석할 수 있습니다.

동시 실행 및 지연 시간

애플리케이션의 지연 시간은 트래픽을 처리하는 데 필요한 인스턴스 수에 가장 큰 영향을 줍니다. 요청을 신속하게 처리하면 단일 인스턴스로 많은 요청을 처리할 수 있습니다.

단일 스레드 인스턴스는 동시 요청 한 개를 처리할 수 있으므로 지연 시간과 초당 인스턴스에서 처리할 수 있는 요청 수 사이에는 직접적인 관계가 있습니다. 예를 들어 10ms 지연 시간은 100 요청/초/인스턴스에 해당됩니다.

다중 스레드 인스턴스는 다수의 동시 요청을 처리할 수 있으므로, 소비된 CPU와 초당 요청 수 사이에는 직접적인 관계가 있습니다.

Python 버전 2.7 앱은 동시 요청을 지원하므로 단일 인스턴스가 다른 요청이 완료될 때까지 기다리는 동안 새 요청을 처리할 수 있습니다. 동시 실행으로 인해 앱에 필요한 인스턴스 수가 상당히 줄어들지만 앱을 멀티 스레딩을 사용하도록 설계해야 합니다.

예를 들어 B4 인스턴스(약 2.4GHz)가 요청당 10Mcycle을 소비하는 경우 인스턴스별로 초당 요청 240개를 처리할 수 있습니다. 인스턴스가 요청당 100Mcycle을 소비하는 경우, 초 및 인스턴스당 요청 24개를 처리할 수 있습니다. 이러한 수치는 이상적인 경우이지만 하나의 인스턴스에서 달성할 수 있는 결과라는 측면에서 상당히 현실적입니다.

환경 변수

다음 환경 변수는 런타임에서 설정됩니다.

환경 변수 설명
GAE_APPLICATION App Engine 애플리케이션 ID입니다. 이 ID는 유럽에 배포된 애플리케이션의 'e~'와 같이 'region code~'로 시작됩니다.
GAE_DEPLOYMENT_ID 현재 배포 ID입니다.
GAE_ENV App Engine 환경입니다. standard로 설정합니다.
GAE_INSTANCE 서비스가 현재 실행되고 있는 인스턴스 ID입니다.
GAE_RUNTIME app.yaml 파일에 지정된 런타임입니다.
GAE_SERVICE app.yaml 파일에 지정된 서비스 이름입니다. 서비스 이름을 지정하지 않으면 default로 설정됩니다.
GAE_VERSION 서비스의 현재 버전 라벨입니다.
GOOGLE_CLOUD_PROJECT 애플리케이션과 연결된 Google Cloud 프로젝트 ID입니다.
PORT HTTP 요청을 수신하는 포트입니다.

app.yaml 파일에 추가 환경 변수를 정의할 수 있지만 위의 값을 재정의할 수 없습니다.