IBM CloudのFunctionsを使って、サーバー無しでコード実行する
IBM Cloud のサーバーレスでコードを実行できるサービス Functions(FaaS)サービスを使って、毎時00分になったらNoSQLのCloudantデータベースに値を書き込むサンプル。LinuxのCronみたいな使い方ができる。
悲しいお知らせ: IBM Cloud Functionsは2023年12月28日でサービス提供が終了になりました。今後は、IBM Cloud Code Engine を使います。
Functionsで何ができるの?
AWS Lambda, Azure Functions とほぼ同じサービス。Linuxサーバーが無くても、さまざまなイベントをトリガーに軽量なコードを実行することができる。
実際には何に使ったの?
IoTデータのグラフを表示するWEBアプリを試したくて、データはダミーでいいのだが、時系列の経過と供に追加される値が欲しかったので、毎時00分にダミーデータを出力させてみた。コードはこの後、拡張していくのだが、一番シンプルなコードで記事化しておく。
起動できるイベントの種類
- Github
- イベントストリーム
- スケジュール(Cronみたいな定期的に実行)
- オブジェクトストレージ
- NoSQL(Cloudant)
- モバイルプッシュ
無料枠を利用できる
メモリ400,000GB秒までが無料と記載されているがムズイ。例えば、メモリ256MBでコード実行時間10秒の時、1ヶ月に45,000回実行するときは無料だ。45,000回というのは毎分であり(=60分x24時間x31日間)この時メモリ115,200GB秒だろう。この条件でコード実行時間が39秒を超えると有料になったが、それでも70円/月くらい。
Functionsの初期設定
IBM Cloud 管理ポータルで新しいリソースを追加する。Functionsの場合は、最初にIAM管理される「名前空間」を作ります。
好きな名前を定義して、リージョンを選びます。ロケーションって書いてありますね。東京リージョンを選びました。
アクションの作成
アクション名を定義してランタイムを選びます。
こんな選択画面(↓)が表示されますが、とりあえずアクションを選びます(あとでトリガーを設定する)。
コードを記述
ランタイムを選んでアクション作成ボタンを押すと、すぐにコード記述する画面になります。
コード記述欄には、最小のひな形が記述済みです。
▼pythonの場合
# main() このアクションを呼び出すときに実行されます
# @param Cloud Functions アクションは 1 つのパラメーターを受け入れます。
# このパラメーターは JSON オブジェクトでなければなりません。
# @return このアクションの出力。この出力は、JSON オブジェクトでなければなりません。
import sys
def main(dict):
return { 'message': 'Hello world' }
▼ Node.jsの場合
/**
* main() このアクションを呼び出すときに実行されます
* @param Cloud Functions アクションは 1 つのパラメーターを受け入れます。
* このパラメーターは JSON オブジェクトでなければなりません。
* @return このアクションの出力。この出力は、JSON オブジェクトでなければなりません。
*/
function main(params) {
return { message: 'Hello World' };
}
FunctionsのPythonコードでCloudantにドキュメント1個を書き込みするコード
# IBM Cloud, Functions アクション
import sys
import datetime
import os
import random
from cloudant.client import Cloudant
from cloudant.error import CloudantException
from cloudant.result import Result, ResultByKey
# DBアクセス認証
serviceUsername = "apikey-v2-***************************"
servicePassword = "*************************"
serviceURL = "https://apikey-v2-2v**********-bluemix.cloudantnosqldb.appdomain.cloud"
def main(dict):
# DBに接続する
client = Cloudant(serviceUsername, servicePassword, url=serviceURL)
client.connect()
myDB_kano = client.create_database("first-db")
# 新しいドキュメントを作成する
objToday = datetime.datetime.today()
strTemp = str(objToday.year) + str(objToday.month) + str(objToday.day) + str(objToday.hour) + str(objToday.minute)
strComment = random.random()
jsonDocument = {
"_id": ":".join(("docid", strTemp)),
"table": 'hogehoge',
"comment": strComment
}
newDocument = myDB_kano.create_document(jsonDocument)
return { 'message': 'Cloueantにドキュメント1個追加したよ' }
コード実行を起動するトリガーを追加
イベントを選びます
毎時、毎分、もしくは曜日、その組み合わせは[Periodic]を選びます
あとでトリガーのパラメータを見直しするGUIが見つからないので、トリガーの名称に「Every Hour」など分かりやすく定義することを強く推奨します。
正しく動作するかテスト
応答があるまで待つ。。。。7-8秒かかった。。(↓)これ成功の場合
トリガー駆動も、NoSQL(Cloudant)にドキュメントが追加されているのでテスト成功
まとめ
このコードは毎時、データを追加するだけの簡単なスケジュール処理を実行できた。
- 駆動するイベントは、Githubやストレージなどさまざまあり
- コードのランタイムは、Node.js, Python, Ruby, Swift, PHP, Goとさまざまに選べる
- Functionsの可用性は高そうだ。東京リージョンで単一障害点を回避しつつ、リージョン丸ごと災害した時はヨーロッパに自動的にフェイルオーバーできるようにFunctionで実行するコードが自動的に同期とられている。
▼Functions入門ドキュメント