Google Cloud Functionsを試す with Python 3.7
Cloud Functionsは、端的にいえばAWS LambdaのGoogle Cloud版だ。要するに、比較的小規模なコードをデプロイしておいて、何らかのトリガに応じてそれを実行させて、実行された時間分だけ課金される、という仕組みで、俗に「サーバレス」と呼ばれているものの礎の1つでもある。
AWS Lambdaと比べて
Cloud Functionsの特徴としては:
- HTTPトリガー(要するにWebhook)が最も基本的なトリガーである。
- 汎用的な仕組みなのでロックインされにくい。
- 外部サービスなどからのWebhook連携がシンプルに実現できる。HTTPエンドポイントを別途に設定しなくていいので、構成がシンプルだし、ロックインも軽減できる。
- 使える言語: Python 3.x, Node.js, Go, (近日サポート?: Ruby, Java, PHP)
- Pythonの場合は:
- 依存パッケージは、pipのrequirements.txtに書いておくだけでインストールされる。
- HTTPトリガの処理にはFlaskが使われる。
AWS Lambdaと比べて、簡便であることを重視している印象を受ける。
Functionを作る
基本的には公式ドキュメントのYour First Function: Pythonの通りにすればいいので、そこに載ってないことだけ書いておく。
Functions Frameworkを使う
最近になってFunctions Frameworkというライブラリが用意されたようだ。これは、実行環境(ローカル環境 / Cloud Functions / Cloud Run)を選ばずに、Functionを実行するためのもので…といっても大げさなものではなくて、例えばPython版の場合は単にFlaskやGunicornによる実行を遮蔽しているに過ぎない。
Functions Frameworkを利用して、Functionを作ってみる。
$ pip3 install functions-framework -U
main.py
def hello(request):
return "Hi"
requirements.txt
# 今回は空っぽ
そして以下のように実行すると、Flaskアプリケーションとして実行される:
$ functions-framework --target=hello --debug
Functionをデプロイする
以下のコマンドでデプロイできる。デプロイを上書きする時も同じ。
$ gcloud functions deploy <name> \
--project <project-name> \
--region=asia-northeast1 \
--runtime=python37 \
--entry-point=hello \
--trigger-http \
--allow-unauthenticated
ここでは以下を指定している。
- リージョンはasia-northeast1(東京)
- ランタイムはPython3.7
- トリガはHTTP
- 認証なし
デプロイには1分くらいかかる。
他のGoogle Cloudサービスを呼ぶ
作ったFunctionから他のGoogle Cloudサービスを呼ぶには当然ながらCredentials(認証情報)が必要になる。Cloud Functionsにおいては、環境変数GOOGLE_APPLICATION_CREDENTIALS
を明示的に設定していない限り、デフォルトのCredentialsが自動的に取得される(内部的には、公式ライブラリがMetadata Serviceから取得してきてくれるっぽい)。
https://google-auth.readthedocs.io/en/latest/reference/google.auth.html#google.auth.default
この仕組みによって、コードベースなどにCredentialsを入れることなしに、他のGoogle Cloudのサービスを呼ぶことができる。例えばCloud Visionを使いたいなら、以下のようにするだけでいい。
client = vision.ImageAnnotatorClient()
Credentials自体が必要なときは、google-authモジュールを使えばいい。
import google.auth
(creds, _) = google.auth.default(scopes=["https://www.googleapis.com/auth/drive"])
drive_service = build("drive", "v3", credentials=creds)
データストア / 永続化
これはどうすればいいのかまだ考えていない。「ちょっとした自動化」程度のアプリケーションを除けば、多くの場合に、状態を保存するための場所が必要になる。Cloud Firestoreが最も手軽だろうか。
デプロイ後の監視など
エラー追跡
- 標準の仕組み: 発生した例外は Cloud Error Reporting に集積される。
- ただし通知はメール通知のみ
- Sentryなどのサードパーティのエラーモニタリングサービスのほうが高機能
- サーバレス環境用のPythonデコレータが提供されている。
- Slackへの通知などもできる
ロギング
- 標準の仕組み: 以下は Cloud Logging に記録される
- stdout, stderrへの出力
- Cloud Logging ライブラリによるログ出力(Pythonのloggingモジュール用のハンドラあり)
- 用途によってはPapertrailやlogDNAといった、ログをLive tailできるサービスも便利かもしれない(これらにはPythonのloggingモジュール用のハンドラもある)