1. 概要
サーバーレス移行ステーション シリーズの Codelab(ご自分のペースで進められる実践型のチュートリアル)と関連動画は、主にレガシー サービスからの移行を 1 つ以上行うことで、Google Cloud サーバーレスのデベロッパーがアプリケーションをモダナイズできるよう支援することを目的としています。これにより、アプリの移植性が向上し、オプションと柔軟性が高まるため、幅広い Cloud プロダクトとの統合やアクセスが可能になり、新しい言語リリースへのアップグレードが容易になります。このシリーズは、当初は初期の Cloud ユーザー、主に App Engine(標準環境)のデベロッパーを対象としていましたが、Cloud Functions や Cloud Run などの他のサーバーレス プラットフォームや、該当する場合は他のプラットフォームも対象とするほど幅広くなっています。
この Codelab では、モジュール 1 の Codelab のサンプルアプリで App Engine タスクキューの push タスクを使用する方法について説明します。モジュール 7 のブログ投稿と動画は、このチュートリアルを補完するもので、このチュートリアルの内容の概要を説明しています。
このモジュールでは、push タスクの使用を追加し、その使用をモジュール 8 で Cloud Tasks に、モジュール 9 で Python 3 と Cloud Datastore に移行します。pull タスクにタスクキューを使用している場合は、Cloud Pub/Sub に移行します。代わりにモジュール 18 ~ 19 を参照してください。
GCP コンソールの
- App Engine Task Queue API/バンドル サービスを使用する
- 基本的な Python 2 Flask App Engine NDB アプリにプッシュタスクの使用量を追加する
必要なもの
- 有効な GCP 請求先アカウントを持つ Google Cloud プロジェクト
- 基本的な Python スキル
- 一般的な Linux コマンドに関する実践的な知識
- App Engine アプリの開発とデプロイに関する基礎知識
- 正常に機能するモジュール 1 App Engine アプリ(その Codelab を完了する [推奨]、またはリポジトリからアプリをコピーする)
アンケート
このチュートリアルをどのように使用されますか?
Python のご利用経験はどの程度ありますか?
Google Cloud サービスの使用経験はどの程度ありますか?
2. 背景情報
App Engine Task Queue は、push タスクと pull タスクの両方をサポートしています。アプリケーションの移植性を高めるため、Google Cloud チームは、Task Queue などの以前のバンドル サービスから、他の Cloud スタンドアロン サービスまたは同等のサードパーティ サービスへの移行をおすすめします。
- Task Queue の push タスクのユーザーは、Cloud Tasks に移行する必要があります。
- Task Queue の pull タスクのユーザーは、Cloud Pub/Sub に移行する必要があります。
プルタスクの移行については移行モジュール 18 ~ 19 で説明し、プッシュタスクの移行についてはモジュール 7 ~ 9 で説明します。App Engine タスクキューの push タスクから移行するには、モジュール 1 の Codelab で作成した既存の Flask アプリと App Engine NDB アプリに、その使用方法を追加します。そのアプリでは、新しいページビューが新しいセッションを登録し、ユーザーに最新のセッションを表示します。古い訪問履歴は二度と表示されず、Datastore の容量を占有するため、最も古い訪問履歴を自動的に削除するプッシュタスクを作成します。モジュール 8 では、このアプリをタスクキューから Cloud Tasks に移行します。
このチュートリアルでは、次の手順について説明します。
- セットアップ / 事前作業
- 構成の更新
- アプリケーション コードを変更する
3. セットアップ/事前作業
このセクションでは、次の方法を説明します。
- Cloud プロジェクトを設定する
- ベースライン サンプルアプリを入手する
- ベースライン アプリを(再)デプロイして検証する
これらの手順により、動作するコードから開始できます。
1. プロジェクトのセットアップ
モジュール 1 Codelab を完了している場合は、同じプロジェクト(とコード)を再利用することをおすすめします。または、新しいプロジェクトを作成するか、別の既存のプロジェクトを再利用することもできます。プロジェクトにアクティブな請求先アカウントがあり、App Engine が有効になっていることを確認します。
2. ベースライン サンプルアプリを入手する
この Codelab の前提条件の 1 つは、機能するモジュール 1 App Engine アプリを用意することです。モジュール 1 Codelab を完了する(推奨)か、リポジトリからモジュール 1 アプリをコピーします。ご自分のコードと Google で用意したコードのいずれを使用される場合も、モジュール 1 のコードから開始します。この Codelab では、各ステップを順を追って説明します。最後に、モジュール 7 のリポジトリ フォルダ「FINISH」にあるコードに似たコードが完成します。
- 開始: モジュール 1 フォルダ(Python 2)
- 終了: モジュール 7 フォルダ(Python 2)
- リポジトリ全体(クローン作成または ZIP ファイルのダウンロード)
モジュール 1 のどのアプリを使用しても、フォルダは次のようになります(lib フォルダも含まれる場合があります)。
$ ls README.md main.py templates app.yaml requirements.txt
3. ベースライン アプリを(再)デプロイする
Module 1 アプリを(再)デプロイする手順は次のとおりです。
libフォルダが存在する場合は削除し、pip install -t lib -r requirements.txtを実行してlibを再作成します。Python 2 と 3 の両方がインストールされている場合は、代わりにpip2コマンドを使用する必要があります。gcloudコマンドライン ツールをインストールして初期化し、その使用方法を確認してください。- 発行する
gcloudコマンドごとにPROJECT_IDを入力したくない場合は、gcloud config set projectPROJECT_IDを使用して Cloud プロジェクトを設定します。 gcloud app deployを使用してサンプルアプリをデプロイする- モジュール 1 アプリが期待どおりに動作し、最新のアクセスが問題なく表示されることを確認します(下図を参照)。

4. 構成を更新する
標準の App Engine 構成ファイル(app.yaml、requirements.txt、appengine_config.py)を変更する必要はありません。
5. アプリケーション ファイルを変更する
メインのアプリケーション ファイルは main.py で、このセクションのすべての更新はこのファイルに関連しています。ウェブ テンプレート templates/index.html のマイナー アップデートもあります。このセクションで実装する変更は次のとおりです。
- インポートを更新する
- プッシュタスクを追加
- タスク ハンドラを追加する
- ウェブ テンプレートを更新する
1. インポートを更新する
google.appengine.api.taskqueue をインポートすると、タスクキュー機能が取り込まれます。一部の Python 標準ライブラリ パッケージも必要です。
- 最も古いアクセスを削除するタスクを追加するため、アプリはタイムスタンプを処理する必要があります。つまり、
timeとdatetimeを使用します。 - タスクの実行に関する有用な情報をログに記録するには、
loggingが必要です。
これらのインポートをすべて追加すると、変更前後のコードは次のようになります。
変更前:
from flask import Flask, render_template, request
from google.appengine.ext import ndb
変更後:
from datetime import datetime
import logging
import time
from flask import Flask, render_template, request
from google.appengine.api import taskqueue
from google.appengine.ext import ndb
2. プッシュタスクを追加(タスクのデータを照合し、新しいタスクをキューに追加)
push キューのドキュメントには、「タスクを処理するには、タスクを push キューに追加する必要があります。App Engine には、default という名前のデフォルトの push キューが用意されています。これは、デフォルト設定ですぐに使用できるように構成されています。すべてのタスクをこのデフォルト キューに追加するだけで、これを使用できます。他のキューを作成して構成する必要はありません。」この Codelab では、簡潔にするために default キューを使用します。同じ特性または異なる特性を持つ独自のプッシュキューの定義について詳しくは、プッシュキューの作成に関するドキュメントをご覧ください。
この Codelab の主な目的は、表示されなくなった古いアクセスを Datastore から削除するジョブを持つタスク(default プッシュキュー)を追加することです。ベースライン アプリは、新しい Visit エンティティを作成して各アクセス(/ への GET リクエスト)を登録し、最新のアクセスを取得して表示します。最も古い訪問が再び表示または使用されることはないため、プッシュタスクは表示されている最も古い訪問よりも古いすべての訪問を削除します。これを実現するには、アプリの動作を少し変更する必要があります。
- 最近の訪問をクエリする際に、それらの訪問をすぐに返すのではなく、アプリを変更して、最後に表示された
Visitのタイムスタンプを保存します。これより古い訪問はすべて削除しても安全です。 - このタイムスタンプをペイロードとして含むプッシュタスクを作成し、HTTP
POSTから/trimを介してアクセス可能なタスク ハンドラに転送します。具体的には、標準の Python ユーティリティを使用して Datastore のタイムスタンプを変換し、タスクに(浮動小数点数として)送信しますが、(文字列として)ログに記録し、その文字列をセンチネル値として返してユーザーに表示します。
これらはすべて fetch_visits() で行われます。更新前と更新後のコードは次のようになります。
変更前:
def fetch_visits(limit):
return (v.to_dict() for v in Visit.query().order(
-Visit.timestamp).fetch(limit))
変更後:
def fetch_visits(limit):
'get most recent visits and add task to delete older visits'
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)
taskqueue.add(url='/trim', params={'oldest': oldest})
return (v.to_dict() for v in data), oldest_str
3. タスク ハンドラを追加する(タスク実行時に呼び出されるコード)
古い訪問の削除は fetch_visits() で簡単に実行できますが、この機能はエンドユーザーとはあまり関係がないことを認識してください。補助的な機能であり、標準アプリ リクエストの外部で非同期で処理するのに適しています。Datastore に保存される情報が少なくなるため、エンドユーザーはクエリの高速化というメリットを享受できます。Task Queue POST リクエストを介して /trim に呼び出される新しい関数 trim() を作成します。この関数は次の処理を行います。
- 「最古の訪問」タイムスタンプ ペイロードを抽出します
- そのタイムスタンプより古いすべてのエンティティを見つける Datastore クエリを発行します。
- 実際のユーザーデータは必要ないため、高速な「キーのみ」のクエリを選択します。
- 削除するエンティティの数(ゼロを含む)をログに記録します。
- エンティティを削除する
ndb.delete_multi()を呼び出します(存在しない場合はスキップされます)。 - 空の文字列を返します(暗黙的な HTTP 200 戻りコードも返します)。
以下の trim() で、これらすべてを確認できます。main.py の fetch_visits() の直後に次のコードを追加します。
@app.route('/trim', methods=['POST'])
def trim():
'(push) task queue handler to delete oldest visits'
oldest = request.form.get('oldest', type=float)
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
4. ウェブ テンプレートを更新する
この Jinja2 条件を使用してウェブ テンプレート templates/index.html を更新し、その変数が存在する場合は最も古いタイムスタンプを表示します。
{% if oldest is defined %}
<b>Deleting visits older than:</b> {{ oldest }}</p>
{% endif %}
このスニペットを表示された訪問リストの後、body を閉じる前に追加します。テンプレートは次のようになります。
<!doctype html>
<html>
<head>
<title>VisitMe Example</title>
<body>
<h1>VisitMe example</h1>
<h3>Last 10 visits</h3>
<ul>
{% for visit in visits %}
<li>{{ visit.timestamp.ctime() }} from {{ visit.visitor }}</li>
{% endfor %}
</ul>
{% if oldest is defined %}
<b>Deleting visits older than:</b> {{ oldest }}</p>
{% endif %}
</body>
</html>
6. 概要/クリーンアップ
このセクションでは、アプリをデプロイし、意図したとおりに動作することと、出力に反映されることを確認して、この Codelab を終了します。アプリの検証が完了したら、クリーンアップを行い、次のステップを検討します。
アプリケーションをデプロイして検証する
gcloud app deploy を使用してアプリをデプロイします。出力は、削除されるアクセスを表示する新しい行が下部に追加されている点を除き、モジュール 1 のアプリと同じになります。

以上で、この Codelab は完了です。これで、コードはモジュール 7 リポジトリ フォルダの内容と一致するはずです。これで、モジュール 8 で Cloud Tasks に移行する準備が整いました。
クリーンアップ
全般
現時点で完了した場合は、課金が発生しないように 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/imagesconsole.cloud.google.com/storage/browser/staging.PROJECT_ID.appspot.com- 上記のストレージ リンクは、
PROJECT_IDと *LOC*ーションによって異なります。たとえば、アプリが米国でホストされている場合は「us」になります。
ただし、このアプリケーションや関連する移行 Codelab を続行せず、すべてを完全に削除する場合は、プロジェクトをシャットダウンしてください。
この Codelab に固有
以下のサービスは、この Codelab 固有のものです。詳細については、各プロダクトのドキュメントをご覧ください。
- App Engine タスクキュー サービスでは、タスクキューなどのレガシー バンドル サービスの料金ページに記載されているように、追加の課金は発生しません。
- App Engine Datastore サービスは Cloud Datastore(Datastore モードの Cloud Firestore)によって提供されます。これにも無料枠があります。詳細については、料金ページをご覧ください。
次のステップ
この「移行」では、Module 1 のサンプルアプリに Task Queue push キューの使用を追加し、訪問者の追跡のサポートを追加して、Module 7 のサンプルアプリを作成しました。次の移行では、必要に応じて App Engine push タスクから Cloud Tasks にアップグレードする方法を学習します。2021 年秋の時点で、Python 3 にアップグレードする際に Cloud Tasks に移行する必要はなくなりました。詳しくは、次のセクションをご覧ください。
Cloud Tasks に移行する場合は、モジュール 8 の Codelab に進みます。それ以外にも、Cloud Datastore、Cloud Memorystore、Cloud Storage、Cloud Pub/Sub(pull キュー)などの追加の移行を検討する必要があります。Cloud Run と Cloud Functions へのプロダクト間の移行もあります。すべての Serverless Migration Station コンテンツ(Codelab、動画、ソースコード [利用可能な場合])は、オープンソース リポジトリでアクセスできます。
7. Python 3 への移行
2021 年秋に、App Engine チームは、第 2 世代ランタイム(元々は第 1 世代ランタイムでのみ使用可能)への多くのバンドル サービスのサポートを拡大しました。つまり、アプリを Python 3 に移植する際に、App Engine Task Queue などのバンドル サービスから Cloud Tasks などのスタンドアロンの Cloud またはサードパーティの同等サービスに移行する必要がなくなりました。つまり、次世代ランタイムからバンドル サービスにアクセスするようにコードを改造すれば、Python 3 App Engine アプリで引き続き Task Queue を使用できます。
バンドル サービスの使用状況を Python 3 に移行する方法については、モジュール 17 の Codelab とその対応する動画をご覧ください。このトピックはモジュール 7 の範囲外ですが、モジュール 1 と 7 の両方のアプリの Python 3 バージョンを以下にリンクします。これらのアプリは Python 3 に移植され、App Engine NDB とタスクキューをまだ使用しています。
8. 参考情報
以下に、デベロッパーがこの移行モジュールまたは関連する移行モジュールや関連プロダクトをさらに詳しく調べるための追加リソースを示します。このコンテンツに関するフィードバックを送信できる場所、コードへのリンク、役立つ可能性のあるさまざまなドキュメントなどが含まれます。
Codelab に関する問題/フィードバック
この Codelab に問題が見つかった場合は、提出する前にまず問題を検索してください。新しい問題の検索と登録を行うためのリンク:
移行に関するリソース
モジュール 2(開始)とモジュール 7(終了)のリポジトリ フォルダへのリンクを以下の表に示します。
Codelab | Python 2 | Python 3 |
コード(このチュートリアルでは取り上げません) | ||
モジュール 7(この Codelab) | コード(このチュートリアルでは取り上げません) |
オンライン リソース
このチュートリアルに関連する可能性のあるオンライン リソースは次のとおりです。
App Engine のタスクキュー
- App Engine Task Queue の概要
- App Engine Task Queue の push キューの概要
- Task Queue push キューの作成
queue.yamlリファレンスqueue.yamlと Cloud Tasks- push キューから Cloud Tasks への移行ガイド
- App Engine Task Queue push キューから Cloud Tasks へのドキュメント サンプル
App Engine プラットフォーム
- App Engine のドキュメント
- Python 2 App Engine(標準環境)ランタイム
- Python 2 App Engine で App Engine の組み込みライブラリを使用する
- Python 3 App Engine(スタンダード環境)ランタイム
- Python 2 と 3 の App Engine(スタンダード環境)ランタイムの違い
- Python 2 から 3 への App Engine(スタンダード環境)移行ガイド
- App Engine の料金と割り当てに関する情報
- 第 2 世代の App Engine プラットフォームのリリース(2018 年)
- 第 1 世代と第 2 世代のプラットフォームの比較
- レガシー ランタイムの長期サポート
- ドキュメントの移行サンプル
- コミュニティ提供の移行サンプル
その他のクラウド情報
- Google Cloud Platform での Python
- Google Cloud Python クライアント ライブラリ
- Google Cloud の「常時無料」枠
- Google Cloud SDK(
gcloudコマンドライン ツール) - Google Cloud に関するすべてのドキュメント
動画
ライセンス
この作業はクリエイティブ・コモンズの表示 2.0 汎用ライセンスにより使用許諾されています。