Python 2 App Engine Cloud Dataplex 마이그레이션 Cloud Tasks 앱에서 Python 3 및 Cloud Datastore (모듈 9)

1. 개요

서버리스 마이그레이션 스테이션 Codelab 시리즈 (사용자 주도형 실습 튜토리얼) 및 관련 동영상Google Cloud 서버리스 개발자가 주로 기존 서비스에서 벗어나 하나 이상의 마이그레이션을 통해 애플리케이션을 현대화하도록 돕는 것을 목표로 합니다. 이렇게 하면 앱의 이식성이 향상되고 더 많은 옵션과 유연성이 제공되므로 다양한 Cloud 제품과 통합하고 액세스하고 최신 언어 버전으로 보다 쉽게 업그레이드할 수 있습니다. 이 시리즈는 처음에는 초기 Cloud 사용자, 특히 App Engine (표준 환경) 개발자에 중점을 두고 있지만 Cloud FunctionsCloud Run과 같은 다른 서버리스 플랫폼이나 해당하는 경우 다른 플랫폼을 포함할 만큼 광범위합니다.

이 Codelab의 목적은 모듈 8 샘플 앱을 Python 3으로 포팅하고 Datastore (Datastore 모드의 Cloud Firestore) 액세스를 Cloud Dataplex를 기본 Cloud Datastore 클라이언트 라이브러리로 전환하고 최신 버전의 Cloud Tasks 클라이언트 라이브러리로 업그레이드하는 것입니다.

모듈 7에서 푸시 태스크에 태스크 큐 사용을 추가한 다음 모듈 8에서는 해당 사용을 Cloud Tasks로 이전했습니다. 모듈 9에서는 Python 3와 Cloud Datastore에 대해 계속 알아봅니다. 가져오기 작업에 태스크 큐를 사용하는 사용자는 Cloud Pub/Sub로 마이그레이션되며 모듈 18~19를 참조해야 합니다.

다음 실습에서는

  • 모듈 8 샘플 앱을 Python 3로 포팅
  • Datastore 액세스를 Cloud Dataplex에서 Cloud Datastore 클라이언트 라이브러리로 전환
  • 최신 Cloud Tasks 클라이언트 라이브러리 버전으로 업그레이드

필요한 항목

설문조사

본 가이드를 어떻게 사용하실 계획인가요?

<ph type="x-smartling-placeholder"></ph> 읽어보기만 해도 됩니다. 읽고 연습 활동을 완료하세요

귀하의 Python 사용 경험이 어떤지 평가해 주세요.

초급 중급 고급

귀하의 Google Cloud 서비스 사용 경험을 평가해 주세요.

<ph type="x-smartling-placeholder"></ph> 초보자 중급 숙련도

2. 배경

모듈 7은 Python 2 Flask App Engine 앱에서 App Engine 작업 대기열 내보내기 작업을 사용하는 방법을 보여줍니다. 모듈 8에서는 이 앱을 태스크 큐에서 Cloud Tasks로 마이그레이션합니다. 모듈 9에서는 이러한 여정을 계속하면서 앱을 Python 3으로 포팅하며 Datastore 액세스를 CloudNDB에서 기본 Cloud Datastore 클라이언트 라이브러리로 전환합니다.

Cloud Dataplex는 Python 2와 3에서 모두 작동하므로 앱을 Python 2에서 3으로 포팅하는 App Engine 사용자에게 충분합니다. Cloud Datastore로의 클라이언트 라이브러리를 추가로 이전하는 것은 전적으로 선택사항이며 한 가지 이유만 고려해야 합니다. 이미 App Engine 이외의 앱 (또는 Python 3 App Engine 앱)이 Cloud Datastore 클라이언트 라이브러리에 액세스하고 클라이언트 라이브러리 하나로 통합하려는 경우입니다. Cloud Dataplex는 Python 2 App Engine 개발자를 위해 Python 3 이전 도구로 특별히 제작되었으므로 Cloud Datastore 클라이언트 라이브러리를 사용하는 코드가 아직 없는 경우 이 이전을 고려하지 않아도 됩니다.

마지막으로, Cloud Tasks 클라이언트 라이브러리 개발은 Python 3에서만 계속되므로 '이전' 중입니다. 최종 Python 2 버전 중 하나에서 Python 3 최신 버전까지 있습니다. 다행히 Python 2에 브레이킹 체인지가 없으므로 별도로 취해야 할 조치는 없습니다.

이 가이드에는 다음 단계가 포함됩니다.

  1. 설정/사전 작업
  2. 구성 업데이트
  3. 애플리케이션 코드 수정

3. 설정/사전 작업

이 섹션에서는 다음을 수행하는 방법을 설명합니다.

  1. Cloud 프로젝트 설정
  2. 기준 샘플 앱 가져오기
  3. 기준 앱 (재)배포 및 검증

이러한 단계를 통해 정상적으로 작동하는 코드로 시작하고 Cloud 서비스로 마이그레이션할 준비가 되었는지 확인할 수 있습니다.

1. 프로젝트 설정

모듈 8 Codelab을 완료했다면 동일한 프로젝트와 코드를 재사용합니다. 또는 새 프로젝트를 만들거나 다른 기존 프로젝트를 재사용합니다. 프로젝트에 활성 결제 계정과 사용 설정된 App Engine 앱이 있는지 확인하세요. 이 Codelab을 진행하는 동안 필요에 따라 프로젝트 ID를 찾아서 PROJECT_ID 변수를 발견할 때마다 사용합니다.

2. 기준 샘플 앱 가져오기

기본 요건 중 하나는 작동하는 모듈 8 App Engine 앱이 있습니다. 모듈 8 Codelab을 완료하거나 (권장) 저장소에서 모듈 8 앱을 복사합니다. 여러분의 것이든 Google의 코드든 모듈 8 코드에서 시작합니다('START'). 이 Codelab에서는 이전을 안내하며 모듈 9 저장소 폴더('FINISH')에 있는 코드와 유사한 코드로 마무리합니다.

사용하는 모듈 7 앱과 관계없이 폴더는 아래와 같이 표시되며 lib 폴더도 있을 수 있습니다.

$ ls
README.md               appengine_config.py     requirements.txt
app.yaml                main.py                 templates

3. 기준 앱 (재)배포 및 검증

다음 단계를 실행하여 모듈 8 앱을 배포합니다.

  1. lib 폴더가 있으면 삭제하고 pip install -t lib -r requirements.txt를 실행하여 lib를 다시 채웁니다. 개발 머신에 Python 2와 3이 모두 설치되어 있는 경우 pip2를 대신 사용해야 할 수 있습니다.
  2. gcloud 명령줄 도구를 설치초기화하고 사용을 검토했는지 확인합니다.
  3. (선택사항) 실행하는 각 gcloud 명령어에 PROJECT_ID를 입력하지 않으려면 gcloud config set project PROJECT_ID로 Cloud 프로젝트를 설정합니다.
  4. gcloud app deploy를 사용하여 샘플 앱 배포
  5. 앱이 문제 없이 예상대로 실행되는지 확인합니다. 모듈 8 Codelab을 완료했다면 앱에 최근 방문 기록과 함께 상위 방문자가 표시됩니다 (아래 그림 참고). 하단에는 삭제될 이전 할 일이 표시됩니다.

4aa8a2cb5f527079.png

4. 구성 업데이트

requirements.txt

requirements.txt는 모듈 8과 거의 동일하며 google-cloud-ndbgoogle-cloud-datastore로 대체한다는 한 가지 큰 변경사항만 있습니다. requirements.txt 파일이 다음과 같이 표시되도록 변경합니다.

flask
google-cloud-datastore
google-cloud-tasks

requirements.txt 파일에는 버전 번호가 없습니다. 즉, 최신 버전이 선택됩니다. 비호환성이 발생할 경우 버전 번호를 사용하여 앱의 작업 버전을 종속시키는 것이 표준 관행입니다.

app.yaml

2세대 App Engine 런타임은 2.x에서와 같이 내장된 서드 파티 라이브러리를 지원하지 않으며 비기본 제공 라이브러리의 복사도 지원하지 않습니다. 서드 파티 패키지의 유일한 요구사항은 requirements.txt에 나열하는 것입니다. 따라서 app.yaml의 전체 libraries 섹션이 삭제될 수 있습니다.

또 다른 업데이트는 Python 3 런타임이 자체 라우팅을 수행하는 웹 프레임워크를 사용해야 한다는 것입니다. 따라서 모든 스크립트 핸들러는 auto로 변경되어야 합니다. 그러나 모든 경로를 auto로 변경해야 하고 이 샘플 앱에서 제공되는 정적 파일이 없으므로 어떤 핸들러도 없어도 되므로 전체 handlers 섹션도 삭제합니다.

app.yaml에 필요한 유일한 작업은 런타임을 지원되는 Python 3 버전(예: 3.10)으로 설정하는 것입니다. 축약된 새 app.yaml가 다음 한 줄이 되도록 다음과 같이 변경합니다.

runtime: python310

appengine_config.py 및 lib 삭제

차세대 App Engine 런타임으로 서드 파티 패키지 사용이 개선되었습니다.

  • 기본 제공 라이브러리는 Google이 심사하여 App Engine 서버에서 사용할 수 있는 라이브러리로, 개발자가 클라우드에 배포할 수 없는 C/C++ 코드가 포함되어 있기 때문일 수 있습니다. 2세대 런타임에서는 더 이상 사용할 수 없습니다.
  • 2세대 런타임에서는 내장되지 않은 라이브러리('벤더링' 또는 '자체 번들링'이라고도 함)를 더 이상 복사할 필요가 없습니다. 대신, 빌드 시스템에서 배포 시에 개발자를 대신해 자동으로 설치하는 requirements.txt에 나열되어야 합니다.

서드 파티 패키지 관리에 대한 이러한 변경사항으로 인해 appengine_config.py 파일과 lib 폴더가 모두 필요하지 않으므로 삭제하세요. 2세대 런타임에서는 App Engine이 requirements.txt에 나열된 서드 파티 패키지를 자동으로 설치합니다. 요약:

  1. 자체적으로 번들로 제공하거나 복사한 서드 파티 라이브러리 금지 requirements.txt에 표시
  2. lib 폴더로 pip install을 수행하지 않음, lib 폴더 기간 없음
  3. app.yaml에 내장된 서드 파티 라이브러리가 나열되지 않습니다 (따라서 libraries 섹션이 없음). requirements.txt에 표시
  4. 앱에서 참조할 서드 파티 라이브러리가 없어 appengine_config.py 파일이 없음

원하는 모든 서드 파티 라이브러리를 requirements.txt에 나열하는 것이 유일한 개발자 요구사항입니다.

5. 애플리케이션 파일 업데이트

애플리케이션 파일(main.py) 하나만 있으므로 이 섹션의 모든 변경사항은 해당 파일에만 영향을 미칩니다. 다음은 '차이점'입니다. 기존 코드를 새 앱으로 리팩터링하기 위해 필요한 전반적인 변경사항을 보여주는 그림입니다. 독자는 코드를 한 줄씩 읽지 않아도 됩니다. 이 리팩터링의 목적은 단순히 이 리팩터링에 필요한 항목의 그림 개요를 얻는 것이기 때문입니다 (단, 새 탭에서 열거나 원하는 경우 다운로드하여 확대해도 됨).

5d043768ba7be742.png

가져오기 및 초기화 업데이트

모듈 8의 main.py에 있는 가져오기 섹션에서는 Cloud NFS와 Cloud Tasks를 사용합니다. 다음과 같이 표시됩니다.

이전:

from datetime import datetime
import json
import logging
import time
from flask import Flask, render_template, request
import google.auth
from google.cloud import ndb, tasks

app = Flask(__name__)
ds_client = ndb.Client()
ts_client = tasks.CloudTasksClient()

Python 3과 같은 2세대 런타임에서는 로깅이 간소화되고 향상되었습니다.

  • 포괄적인 로깅 경험을 위해 Cloud Logging을 사용합니다.
  • 간단한 로깅의 경우 print()를 통해 stdout (또는 stderr)로 전송하면 됩니다.
  • Python logging 모듈을 사용할 필요가 없으므로 삭제합니다.

따라서 logging 가져오기를 삭제하고 google.cloud.ndbgoogle.cloud.datastore로 바꿉니다. 마찬가지로 ds_client가 Ndd 클라이언트 대신 Datastore 클라이언트를 가리키도록 변경합니다. 이렇게 변경하면 새 앱의 상단이 다음과 같이 표시됩니다.

변경 후:

from datetime import datetime
import json
import time
from flask import Flask, render_template, request
import google.auth
from google.cloud import datastore, tasks

app = Flask(__name__)
ds_client = datastore.Client()
ts_client = tasks.CloudTasksClient()

Cloud Datastore로 마이그레이션

이제 Dataplex 클라이언트 라이브러리 사용량을 Datastore로 대체할 차례입니다. App Engine NDB와 Cloud Dataplex에는 모두 데이터 모델 (클래스)이 필요합니다. 이 앱의 경우 Visit입니다. store_visit() 함수는 다른 모든 이전 모듈에서 동일하게 작동합니다. 즉, 새 Visit 레코드를 만들어 방문을 등록하고 방문 클라이언트의 IP 주소와 사용자 에이전트 (브라우저 유형)를 저장합니다.

이전:

class Visit(ndb.Model):
    'Visit entity registers visitor IP address & timestamp'
    visitor   = ndb.StringProperty()
    timestamp = ndb.DateTimeProperty(auto_now_add=True)

def store_visit(remote_addr, user_agent):
    'create new Visit entity in Datastore'
    with ds_client.context():
        Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()

하지만 Cloud Datastore는 데이터 모델 클래스를 사용하지 않으므로 이 클래스를 삭제하세요. 또한 Cloud Datastore는 레코드가 생성될 때 타임스탬프를 자동으로 생성하지 않으므로 datetime.now() 호출을 통해 수동으로 해야 합니다.

데이터 클래스가 없으면 수정된 store_visit()는 다음과 같습니다.

변경 후:

def store_visit(remote_addr, user_agent):
    'create new Visit entity in Datastore'
    entity = datastore.Entity(key=ds_client.key('Visit'))
    entity.update({
        'timestamp': datetime.now(),
        'visitor': '{}: {}'.format(remote_addr, user_agent),
    })
    ds_client.put(entity)

키 함수는 fetch_visits()입니다. 최신 Visit에 관한 원래 쿼리를 실행할 뿐만 아니라 표시된 마지막 Visit의 타임스탬프를 가져와 /trim (결과적으로 trim())를 호출하여 이전 Visit를 대량 삭제하는 푸시 작업을 만듭니다. 여기에서는 Cloud NFS를 사용합니다.

이전:

def fetch_visits(limit):
    'get most recent visits & add task to delete older visits'
    with ds_client.context():
        data = Visit.query().order(-Visit.timestamp).fetch(limit)
    oldest = time.mktime(data[-1].timestamp.timetuple())
    oldest_str = time.ctime(oldest)
    logging.info('Delete entities older than %s' % oldest_str)
    task = {
        'app_engine_http_request': {
            'relative_uri': '/trim',
            'body': json.dumps({'oldest': oldest}).encode(),
            'headers': {
                'Content-Type': 'application/json',
            },
        }
    }
    ts_client.create_task(parent=QUEUE_PATH, task=task)
    return (v.to_dict() for v in data), oldest_str

주요 변경사항은 다음과 같습니다.

  1. Cloud Dataplex 쿼리를 동등한 Cloud Datastore 쿼리로 바꿉니다. 쿼리 스타일이 약간 다릅니다
  2. Datastore는 컨텍스트 관리자를 사용할 필요가 없으며 Cloud NDB처럼 사용자가 to_dict()를 사용하여 데이터를 추출하도록 하지 않습니다.
  3. 로깅 호출을 print()로 대체

이러한 변경사항을 적용하면 fetch_visits()가 다음과 같이 표시됩니다.

변경 후:

def fetch_visits(limit):
    'get most recent visits & add task to delete older visits'
    query = ds_client.query(kind='Visit')
    query.order = ['-timestamp']
    visits = list(query.fetch(limit=limit))
    oldest = time.mktime(visits[-1]['timestamp'].timetuple())
    oldest_str = time.ctime(oldest)
    print('Delete entities older than %s' % oldest_str)
    task = {
        'app_engine_http_request': {
            'relative_uri': '/trim',
            'body': json.dumps({'oldest': oldest}).encode(),
            'headers': {
                'Content-Type': 'application/json',
            },
        }
    }
    ts_client.create_task(parent=QUEUE_PATH, task=task)
    return visits, oldest_str

일반적으로는 여기까지만 하면 됩니다. 하지만 한 가지 중요한 문제가 있습니다.

새(푸시) 큐 만들기

모듈 7에서는 기존 모듈 1 앱에 App Engine taskqueue 사용을 추가했습니다. 내보내기 작업을 기존 App Engine 기능으로 사용할 때 얻을 수 있는 주요 이점 중 하나는 '기본' 자동으로 생성됩니다 해당 앱이 모듈 8에서 Cloud Tasks로 이전되었을 때는 이미 기본 대기열이 있었기 때문에 그 당시에는 여전히 신경 쓸 필요가 없었습니다. 이 점은 모듈 9에서 변경됩니다.

고려해야 할 한 가지 중요한 측면은 새로운 App Engine 애플리케이션에서 더 이상 App Engine 서비스를 사용하지 않는다는 것입니다. 따라서 App Engine이 자동으로 다른 제품 (Cloud Tasks)에서 태스크 큐를 자동으로 생성한다고 가정할 수 없습니다. 앞서 설명한 바와 같이 fetch_visits()에서 작업 (존재하지 않는 큐의 경우)을 만드는 것은 실패합니다. ('기본값') 큐가 있는지 확인하고 없으면 새로 만들려면 새 함수가 필요합니다.

이 함수를 _create_queue_if()로 호출하고 fetch_visits() 바로 위에 있는 애플리케이션에 추가합니다. 이 함수가 호출되는 곳이기 때문입니다. 추가할 함수의 본문입니다.

def _create_queue_if():
    'app-internal function creating default queue if it does not exist'
    try:
        ts_client.get_queue(name=QUEUE_PATH)
    except Exception as e:
        if 'does not exist' in str(e):
            ts_client.create_queue(parent=PATH_PREFIX,
                    queue={'name': QUEUE_PATH})
    return True

Cloud Tasks create_queue() 함수에는 큐 이름을 제외한 큐의 전체 경로 이름이 필요합니다. 편의상 QUEUE_PATH에서 큐 이름 (QUEUE_PATH.rsplit('/', 2)[0])을 뺀 다른 변수 PATH_PREFIX를 만듭니다. 모든 상수 할당이 포함된 코드 블록이 다음과 같도록 상단에 정의를 추가합니다.

_, PROJECT_ID = google.auth.default()
REGION_ID = 'REGION_ID'    # replace w/your own
QUEUE_NAME = 'default'     # replace w/your own
QUEUE_PATH = ts_client.queue_path(PROJECT_ID, REGION_ID, QUEUE_NAME)
PATH_PREFIX = QUEUE_PATH.rsplit('/', 2)[0]

이제 _create_queue_if()를 사용하도록 fetch_visits()의 마지막 줄을 수정합니다. 필요한 경우 먼저 큐를 만들고 그런 다음 나중에 태스크를 만듭니다.

    if _create_queue_if():
        ts_client.create_task(parent=QUEUE_PATH, task=task)
    return visits, oldest_str

이제 _create_queue_if()fetch_visits() 모두 다음과 같이 집계되어 표시됩니다.

def _create_queue_if():
    'app-internal function creating default queue if it does not exist'
    try:
        ts_client.get_queue(name=QUEUE_PATH)
    except Exception as e:
        if 'does not exist' in str(e):
            ts_client.create_queue(parent=PATH_PREFIX,
                    queue={'name': QUEUE_PATH})
    return True

def fetch_visits(limit):
    'get most recent visits & add task to delete older visits'
    query = ds_client.query(kind='Visit')
    query.order = ['-timestamp']
    visits = list(query.fetch(limit=limit))
    oldest = time.mktime(visits[-1]['timestamp'].timetuple())
    oldest_str = time.ctime(oldest)
    print('Delete entities older than %s' % oldest_str)
    task = {
        'app_engine_http_request': {
            'relative_uri': '/trim',
            'body': json.dumps({'oldest': oldest}).encode(),
            'headers': {
                'Content-Type': 'application/json',
            },
        }
    }
    if _create_queue_if():
        ts_client.create_task(parent=QUEUE_PATH, task=task)
    return visits, oldest_str

이 추가 코드를 추가하지 않아도 Cloud Tasks 코드의 나머지는 대부분 모듈 8에서 그대로 유지됩니다. 마지막으로 살펴볼 코드는 작업 핸들러입니다.

(push) 태스크 핸들러 업데이트

태스크 핸들러 trim()에서 Cloud Dataplex 코드는 가장 오래된 방문 시간보다 오래된 방문을 쿼리합니다. 키 전용 쿼리를 사용하여 작업 속도를 높입니다. 방문 ID만 필요한데 왜 모든 데이터를 가져와야 할까요? 방문 ID가 모두 준비되었으면 Cloud NBS의 delete_multi() 함수를 사용하여 일괄 삭제합니다.

이전:

@app.route('/trim', methods=['POST'])
def trim():
    '(push) task queue handler to delete oldest visits'
    oldest = float(request.get_json().get('oldest'))
    with ds_client.context():
        keys = Visit.query(
                Visit.timestamp < datetime.fromtimestamp(oldest)
        ).fetch(keys_only=True)
        nkeys = len(keys)
        if nkeys:
            logging.info('Deleting %d entities: %s' % (
                    nkeys, ', '.join(str(k.id()) for k in keys)))
            ndb.delete_multi(keys)
        else:
            logging.info(
                    'No entities older than: %s' % time.ctime(oldest))
    return ''   # need to return SOME string w/200

fetch_visits()와 마찬가지로 대부분의 변경사항에는 Cloud Datastore를 Cloud Datastore로 교체하고, 쿼리 스타일을 조정하고, 컨텍스트 관리자 사용을 삭제하고, 로깅 호출을 print()로 변경하는 것이 포함됩니다.

변경 후:

@app.route('/trim', methods=['POST'])
def trim():
    '(push) task queue handler to delete oldest visits'
    oldest = float(request.get_json().get('oldest'))
    query = ds_client.query(kind='Visit')
    query.add_filter('timestamp', '<', datetime.fromtimestamp(oldest))
    query.keys_only()
    keys = list(visit.key for visit in query.fetch())
    nkeys = len(keys)
    if nkeys:
        print('Deleting %d entities: %s' % (
                nkeys, ', '.join(str(k.id) for k in keys)))
        ds_client.delete_multi(keys)
    else:
        print('No entities older than: %s' % time.ctime(oldest))
    return ''   # need to return SOME string w/200

기본 애플리케이션 핸들러 root()에는 변경사항이 없습니다.

Python 3로 포팅

이 샘플 앱은 Python 2와 3에서 모두 실행되도록 설계되었습니다. 모든 Python 3 관련 변경사항은 앞서 이 튜토리얼의 관련 섹션에서 다루었습니다. 추가 단계나 호환성 라이브러리는 필요하지 않습니다.

Cloud Tasks 업데이트

Python 2를 지원하는 Cloud Tasks 클라이언트 라이브러리의 최종 버전은 1.5.0입니다. 이 문서를 작성하는 시점을 기준으로, Python 3용 클라이언트 라이브러리의 최신 버전은 해당 버전과 완벽하게 호환되므로 추가 업데이트가 필요하지 않습니다.

HTML 템플릿 업데이트

HTML 템플릿 파일 templates/index.html도 변경할 필요가 없으므로, 이렇게 하면 모듈 9 앱에 도달하는 데 필요한 모든 변경사항이 마무리됩니다.

6. 요약/삭제

애플리케이션 배포 및 확인

코드 업데이트(주로 Python 3으로의 포팅)를 완료했으면 gcloud app deploy를 사용하여 앱을 배포합니다. 데이터베이스 액세스를 Cloud Datastore 클라이언트 라이브러리로 이동하고 Python 3으로 업그레이드했다는 점을 제외하면 출력은 모듈 7 및 8 앱의 앱과 동일해야 합니다.

모듈 7 visitme 앱

이 단계로 Codelab이 완료되었습니다. 작성한 코드를 모듈 9 폴더의 코드와 비교해 보세요. 축하합니다.

삭제

일반

이 작업이 완료되면 요금이 청구되지 않도록 App Engine 앱을 사용 중지하는 것이 좋습니다. 하지만 추가 테스트 또는 실험을 원하는 경우 App Engine 플랫폼에서 무료 할당량을 사용할 수 있으므로 이 사용 등급을 초과하지 않는 한 요금이 청구되지 않습니다. 이는 컴퓨팅을 위한 것이며, 관련 App Engine 서비스에 대한 요금이 부과될 수 있으므로 자세한 내용은 가격 책정 페이지를 확인하세요. 이 마이그레이션에 다른 Cloud 서비스가 포함된 경우 별도로 요금이 청구됩니다. 두 경우 모두 해당하는 경우 '이 Codelab과 관련된 내용'을 참고하세요. 섹션을 참조하세요.

자세히 알려드리자면 App Engine과 같은 Google Cloud 서버리스 컴퓨팅 플랫폼에 배포할 경우 약간의 빌드 및 스토리지 비용이 발생합니다. Cloud Build에는 Cloud Storage와 마찬가지로 자체 무료 할당량이 있습니다. 해당 이미지의 스토리지가 할당량 중 일부를 사용합니다. 하지만 이러한 무료 등급이 없는 지역에 거주할 수도 있으므로 잠재적인 비용을 최소화하려면 저장용량 사용량에 유의해야 합니다. 특정 Cloud Storage '폴더' 다음을 포함해야 합니다.

  • console.cloud.google.com/storage/browser/LOC.artifacts.PROJECT_ID.appspot.com/containers/images
  • console.cloud.google.com/storage/browser/staging.PROJECT_ID.appspot.com
  • 위의 스토리지 링크는 PROJECT_ID 및 *LOC*기호에 따라 다릅니다(예: 'us'). (앱이 미국에서 호스팅되는 경우)

반면 이 애플리케이션 또는 다른 관련 이전 Codelab을 계속 진행하지 않고 모든 항목을 완전히 삭제하려면 프로젝트를 종료합니다.

이 Codelab에만 해당

아래에 나열된 서비스는 이 Codelab의 고유한 서비스입니다. 자세한 내용은 각 제품의 문서를 참조하세요.

다음 단계

이로써 App Engine 태스크 큐 푸시 태스크에서 Cloud Tasks로의 마이그레이션이 완료되었습니다. Cloud Dataplex에서 Cloud Datastore로의 선택적 마이그레이션도 모듈 3에서 그 자체 (태스크 큐 또는 Cloud Tasks 제외)를 다룹니다. 모듈 3 외에도 App Engine의 기존 번들 서비스에서 벗어나는 데 중점을 둔 다른 마이그레이션 모듈은 다음과 같습니다.

  • 모듈 2: App Engine NBS에서 Cloud Dataplex로 마이그레이션
  • 모듈 3: Cloud Dataplex에서 Cloud Datastore로 마이그레이션
  • 모듈 12~13: App Engine Memcache에서 Cloud Memorystore로 마이그레이션
  • 모듈 15~16: App Engine blobstore에서 Cloud Storage로 이전
  • 모듈 18~19: Cloud Pub/Sub로 App Engine 태스크 큐 (태스크 가져오기)

Google Cloud의 서버리스 플랫폼은 더 이상 App Engine이 아닙니다. App Engine 앱이 작거나 기능이 제한적이며 독립형 마이크로서비스로 전환하려는 경우 또는 모놀리식 앱을 재사용 가능한 여러 구성요소로 분할하려는 경우 Cloud Functions로 이전하는 것이 좋습니다. 특히 CI/CD (지속적 통합/지속적 배포 또는 배포) 파이프라인으로 구성된 컨테이너화가 애플리케이션 개발 워크플로의 일부가 되었다면 Cloud Run으로 마이그레이션하는 것이 좋습니다. 이러한 시나리오는 다음 모듈에서 다룹니다.

  • App Engine에서 Cloud Functions로 마이그레이션: 모듈 11 참조
  • App Engine에서 Cloud Run으로 마이그레이션: Docker로 앱을 컨테이너화하려면 모듈 4를 참조하고, 컨테이너, Docker 지식 또는 Dockerfile 없이 마이그레이션하려면 모듈 5를 참조하세요.

다른 서버리스 플랫폼으로 전환하는 것은 선택사항이며 변경하기 전에 앱 및 사용 사례에 가장 적합한 옵션을 고려하는 것이 좋습니다.

다음으로 고려할 마이그레이션 모듈과 관계없이 모든 서버리스 마이그레이션 스테이션 콘텐츠 (Codelab, 동영상, 소스 코드[사용 가능한 경우])는 오픈소스 저장소에서 액세스할 수 있습니다. 저장소의 README는 고려할 이전 및 관련 '순서'에 관한 안내도 제공합니다. 오신 것을 환영합니다

7. 추가 리소스

Codelabs 문제/의견

이 Codelab에 문제가 발견된 경우 문제를 기록하기 전에 먼저 비슷한 기록이 있는지 검색해보세요. 검색 및 새 문제 만들기 링크:

마이그레이션 리소스

모듈 8 (START)과 모듈 9 (FINISH)의 저장소 폴더 링크는 아래 표에서 찾을 수 있습니다. 또한 ZIP 파일을 클론하거나 다운로드할 수 있는 모든 App Engine Codelab 이전 저장소에서도 액세스할 수 있습니다.

Codelab

Python 2

Python 3

모듈 8

코드

(해당 없음)

모듈 9

(해당 없음)

코드

온라인 리소스

다음은 이 튜토리얼과 관련이 있을 수 있는 온라인 리소스입니다.

App Engine

Cloud NDB

Cloud Datastore

Cloud Tasks

기타 클라우드 정보

라이선스

이 작업물은 Creative Commons Attribution 2.0 일반 라이선스에 따라 사용이 허가되었습니다.