まだプログラマーですが何か?

プログラマーネタ中心。たまに作成したウェブサービス関連の話も https://twitter.com/dotnsf

IBM Bluemix でアプリケーションサーバーを作った場合、そのサーバーインスタンスの数やメモリ量については管理コンソール画面から(自分が持っているリソースの上限まで)動的に変更できます:
2015032615


サーバーのワークロードがある程度安定しているのであれば、これらの数値を手動で設定すればいいのですが、実際には変化するワークロードに対応するため、何らかの運用ルールを決めた上で自動的にスケールイン/アウトするように設定できると便利です。

IBM Bluemix 環境の場合、このオートスケール機能もサービスの1つとして提供されています。このオートスケールサービス自体は無料でお使いいただけます。


「無料」という意味では1点注意していただきたいのですが、IBM Bluemix はサインアップ後の30日間は無料、有料アカウント移行後もこのオートスケールサービス自体は無料でお使いいただけます。有料アカウント移行後の無料枠があり、その範囲内でご利用いただくぶんには料金は発生しません。 ただし、有料アカウント移行後にこのオートスケールサービス機能でサーバーインスタンスがスケールアウトした結果、いつの間にか無料枠を超えた状態で運用されてしまっている、という可能性がありえます。オートスケールを利用する場合の設定内容と利用料金についてはご注意ください。


では、Bluemix でのオートスケールサービスの使い方について紹介します。まずはオートスケールの対象となるアプリケーションランタイムを用意します。ここでは IBM Bluemix 上に WordPress 環境を構築して、この環境をオートスケールさせてみます(WordPress 環境である必要はありません。何か Bluemix 上で動くランタイム環境があれば、それをお使いいただいても構いません)。Bluemix 上に WordPress 環境を構築する場合の手順は以下を参照ください:
IBM Bluemix 上で WordPress 環境を構築する (少し古い記事)
IBM Bluemix で無料の WordPress 環境を構築する (比較的新しい記事、こちらがオススメ)

オートスケールの設定をするにあたり、まずは CPU やメモリの利用状況を確認します。作成した WordPress ランタイムアプリケーション(下図では dotnsf-wp)を Bluemix ダッシュボードから開き、そのプログラミング言語環境が書かれた部分(下図では PHP)をクリックします:
2015032601


このランタイムアプリケーションの現在の状態が表示されます。下図ではメモリ 128MB の1サーバーインスタンスが稼働していて、CPU 利用率は 0.1%、メモリは 128MB のうち 68.4MB が利用中、そしてディスクは 1GB のうちの 234.8MB を使っている、ということがわかります:
2015032602


この状態を元にオートスケールの条件を決めます。今はテスト的な目的もあるので、わざとスケールアウトを発生させたいため、
  メモリ利用率が 50% を超えたらスケールアウト
  メモリ利用率が 30% を下回ったらスケールイン

という(このままでもスケールアウトが発生するような)条件で運用してみます。この条件は CPU かメモリに対して設定することができますので、実際の環境を確認した上で、簡単に発生させられそうな条件を決めてください。


ではこのランタイムにオートスケールサービスを追加します。ダッシュボードに戻ってこのランタイムを選択した上で、「サービスまたは API の追加」をクリックします:
2015032603


追加できるサービスの一覧が表示されます。DevOps カテゴリーの "Auto-Scaling" サービスを選択してクリックします:
2015032604



Auto-Scaling サービスの説明と利用条件が表示され、無料サービスであることが分かります。右上のアプリ選択欄では、このサービスを追加したいランタイム(この例では dotnsf-wp)が選択されていることを確認して「作成」ボタンをクリックします:
2015032605


サービスを1つ追加したので、ランタイムを再ステージングするか聞かれます。ここで「再ステージ」をクリックしてランタイムサーバーを再ステージングします:
2015032606


しばらく待つと、先ほどのランタイムアプリケーションに Auto-Scaling サービスが追加されていることが確認できるようになります。次はオートスケールの条件を設定したいので、この Auto-Scaling サービスのアイコンをクリックします:
2015032607


オートスケールサービスのパネルが開きます。最初はまだ何のルール(ポリシー)も定義していないので作成する必要があります。「ポリシー構成」タブ内の「自動スケーリングポリシーの作成」ボタンをクリックします:
2015032608


最初のポリシールールを編集する画面になります。名称などは適当に付けるとして、設定すべきは具体的なルールの部分です。まずスケールイン時の最小インスタンス数はデフォルトの1のままとして、スケールアウト時の最大インスタンスは念のため4にしてみます。現在は1インスタンスのメモリが128MBなので、4インスタンスまで稼働させても無料枠内、という安心設定です(笑)。 またメトリックタイプを「メモリー」に、スケールアウトの条件を(メモリ使用率)50% 超えと設定します。これで何もしなくても今のままでスケールアウトしてくれます。 更に細かい条件を設定するため「拡張構成」をクリックします:
2015032609


拡張構成では、どれだけの期間測定してスケールイン/アウトを判断するか?を指定できます。デフォルトでは600秒(10分)になっていますが、今回はなるべくすぐに確認したいので最小値の120秒(2分)に設定し、最後に「保存」ボタンをクリックします:
2015032610


確認メッセージが表示されればポリシーの定義ができました:
2015032611


そのままダッシュボードの言語タブ(下図では "PHP")に移ってしばらく様子を見ていると、スケールアウトの様子が見えてくるはずです。これは1インスタンス増えて2インスタンスになった様子:
2015032612


条件を厳し目に設定したので(苦笑)、2分おきにインスタンスがどんどん増えていきます。設定最大値である4インスタンスまで順調に(?)増えていきました:
2015032613


この状態でダッシュボードの "Auto-Scaling" サービスを選択して、スケーリング履歴タブを開くと、この時のスケールアウトの様子が記録されており、一覧で参照することもできます:
2015032614


IBM Bluemix はアプリケーションサーバーであるランタイムと、データベースなど各種サービスを組み合わせて環境を構築するのが特徴ですが、オートスケーリングに関してもサービスの1つとして提供されており、簡単に使えることも分かっていただけるのではないかと思っています。メモリだけでなく CPU 状態でも設定できるので、用途・目的に合わせて使ってみてください。


前回の、この記事の続きです:
Bluemix の Node-RED サービスで IoT アプリを作る(1/2)


前回は IBM Bluemix 上の Node-RED サービスの初歩的な使い方を中心に説明し、IoT センサーシミュレータと接続し、送られてくるセンサーの値を取得して表示する、というシンプルなワークフローを作りました。 今回は Node-RED の他のブロック機能を組み合わせて、もう少し実用に近いワークフローを記述してみます。

具体的には、以下の様な分岐処理を含むワークフローを Node-RED エディタで記述します:
- IoT センサーから、機器温度の値を取得して、
- 機器温度が40度以下であれば、(安全な状態とみなして)その値を画面に出力して終了
- 機器温度が40度を超えている場合、警告メッセージを画面に出力し、
- 同時にその時の状態をデータベースに記録する


最初に Node-RED エディタでの、上記ワークフローの完成形を示しておきます。前回のシンプルなものと比べると、スタートは IoT デバイスになっていて変わりませんが、プロセスが長くなり、途中に条件分岐が含まれていたり、見たことのない記号のブロックがあったりと、それなりに複雑なフローになっていることがわかると思います:
2015032301


では実際に Node-RED エディタ上でこのワークフローを作っていきます。まずは前回の内容を参照して、Node-RED Starter ボイラープレートを使ってプロジェクトを作ります。この図ではアプリケーションの名称は dotnsf-nodered としましたが、実際には個別の名前を付けることになります。なお、このボイラープレートに含まれる Cloudant データベースサービスの名称が dotnsf-nodedred-cloudantNoSQLDB となっていることを確認しておきます(この名称を後で使います):
2015032401


アプリケーションから Node-RED エディタを開き、"iotibm" ブロックをキャンバスに1つ追加します。このあたりは前回の内容と同じです:
2015032407


iotibm ブロックをダブルクリックして編集状態に移り、このデバイスの属性を入力します。デバイスID(Device Id)欄にはこのデバイスの MAC アドレスを指定しますが、これは最後に入れるので空にしておいても構いません。これが(仮想の) IoT デバイスであり、ここから送られてくるセンサーの値を使ってワークフローを記述します:
2015032402


次にワークフローを進める中でセンサーの機器温度を何度も調べるのは効率が悪いため、「センサーの機器温度だけを取り出す」という処理を最初に行っておきます。こうすることでいちいち JSON テキストを解析することなく、一度取り出した機器温度の値を多くの処理の中でそのまま使うことができるようになるからです。キャンバスの左ペイン内 function カテゴリから "function" と書かれたブロックを1つ追加し、先ほどの "iotibm" ブロックと線で結びます:
2015032408


追加した function ブロックをダブルクリックして編集状態にして、下図のように msg.payload.d.objectTemp(機器温度)に payload という名前を付けて返す、という関数処理を加えます。これによってこの次のブロックからははメッセージの payload プロパティを参照することで機器温度を取得することができるようになります:
2015032401


次のブロックを追加します。同様に function カテゴリから "switch" と書かれたブロックを1つ追加し、先ほどの "function" ブロックと線で結びます:
2015032409


追加した switch ブロックをダブルクリックして編集状態にして、下図のような分岐ルールにします(2つ目のルールは +rule と書かれたボタンをクリックして追加します)。これによって msg.payload の値(=機器温度)が 40 を超えている(=警告)場合はルート1へ、40以下(=正常)の場合はルート2へ、処理を分岐するようにしています:
2015032403


次は分岐の正常処理を用意します。正常処理の場合は単純に画面に機器温度を出力するだけとします。パレットに output カテゴリから "debug" と書かれたブロックを1つ追加し、switch ブロックの下側(ルート2)から線で結びます:
2015032410


追加した debug ブロックをダブルクリックして編集状態にして、下図のような内容(msg.payload の値を debug タブに出力する)にします。機器温度が正常範囲内と判断された場合はこれだけです:
2015032404



次に分岐の警告処理を用意します。警告処理の場合は画面への出力内容にも "Warning!" という文字列を追加して出力し、更にその温度を Cloudant にも記録するようにします。まずは出力内容の文字列を変更するために function カテゴリから "template" ブロックを1つ追加し、switch ブロックの上側(ルート1)から線で結びます。更に追加した template ブロックから、先ほど追加した debug ブロックに向けて線を結びます:
2015032411



追加した template ブロックをダブルクリックして編集状態にして、下図のような内容に書き換えます。payload の値の前に "Warning!: " という文字列を付加するような処理を施しています:
2015032405



更に、この警告時の機器温度をデータベースに追加するためのブロックを追加します。storage カテゴリ内の右側にコネクタがない "Cloudant" ブロックを1つ追加し、template ブロックから線で結びます。なお右側にコネクタがある "Cloudant" ブロックはデータを検索する処理で、検索結果を次のブロックに渡します。右側にコネクタがない "Cloudant" ブロックは単純なデータ追加処理です。今回は後者のブロックを使います:
2015032412


追加した Cloudant ブロックをダブルクリックして編集状態にして、下図のような内容に書き換えます。今回の処理では警告メッセージを、Bluemix のボイラープレートに含まれる Cloudant サービス(dotnsf-nodered-cloudantNoSQLDB)内の iotdata というデータベース内に insert します:
2015032406


この時点で Node-RED エディタのキャンバスに必要なパーツは全て揃いました。

ただ、ここで指定した Cloudant 内の iotdata というデータベースは標準で存在しているわけではないので、このままデータを挿入しようとしてもエラーとなります。そのためこのデータベースを事前に作成しておきます。

改めて Bluemix のダッシュボード画面に戻り、目的のアプリケーション(この例では dotnsf-nodered)を開きます。そして Cloudant サービスのアイコン部分をクリックします:
2015032402


Cloudant NoSQL データベースの説明ページが表示されたら、右上の "LAUNCH" ボタンをクリックして、このデータベースの管理機能にアクセスします:
2015032403


このサービスで利用中の Cloudant データベースの管理画面が表示されます。このボイラープレートを使った時点で "nodered" という名前のデータベースが作られているはずです。今回は新たに機器情報格納用のデータベースを作りたいので、右上の "Add New Database" ボタンをクリックします:
2015032404


追加したいデータベースの名前(今回は "iotdata")を指定して、"Create" ボタンをクリックします:
2015032405


iotdata データベースが追加されたことが確認できたら、Cloudant 側の準備は完了です。この段階ではまだ中身がないのでデータ数(# of Docs)はゼロのはずです:
2015032406


最後に機器温度データを送信する(仮想) IoT 機器の MAC アドレスを指定します。今回は仮想 IoT シミュレータを使うことにしますので、このページにアクセスして仮想 IoT 機器を表示し、右にスワイプして "Object Tempreture"(機器温度)と書かれた画面まで移動します。デフォルト値の 24 度(40度以下)になっていることを確認し、そして画面右上に書かれた MAC アドレスをメモします:
2015032401


この MAC アドレスのコロンを省略して大文字を小文字に変換したものを、Node-RED エディタに最初に追加した IoT Sensor のデバイス ID として指定します。IoT Sensor をダブルクリックし、Device Id 欄に指定して OK をクリックします:
2015032402


これで今回作成した IoT 機器アプリのワークフローは完成です。では実際に動かしてみましょう。Node-RED エディタの右ペインで debug タブを選んだ上で、右上の "Deploy" ボタンをクリックして実行します:
2015032403


画面上部に "Successfully deployed" と表示されれば実行成功です:
2015032404


すぐに画面右ペインの debug タブ内に指定した IoT 機器から送られてくるセンサー情報の機器温度(何も変えていなければ24度)が2秒おきに表示されます:
2015032405


この時点で Cloudant の管理画面を更新しても、まだ(警告になるデータが送られてきていないので) iotdata データベースにはデータが格納されていないはずです:
2015032406


では仮想 IoT 機器の機器温度が上がった状態をシミュレートしてみます。シミュレータのボタンをクリックして、機器温度を45度まで少しずつ上げてみます:
2015032407



41度以上になったタイミングから、ワークフロー内で記述した分岐処理で警告状態と判断され、表示メッセージがカスタマイズされたものに切り替わります:
2015032408


また、41度以上のデータについては Cloudant に格納する、というブロックも追加していました。この状態で iotdata データベースを更新すると、いくつかのデータが格納されていることを確認できます。 詳細を確認してみるには iotdata と書かれた箇所をクリックします:
2015032409


iotdata データベースに格納された情報が一覧表示されます。この状態のままだと個別データが表示されないので、どれか1つ選んで右上の鉛筆マークをクリックしてみます:
2015032410


選択したデータの全情報が表示されます。"payload" 値として設定した通りの "Warning: XXX" という警告メッセージが格納されていることを確認できます:
2015032411



以上、前回よりは少し複雑なワークフロー処理を Node-RED エディタを使って実現してみました。事実上、コーディング処理は1行も記述していませんが、IoT 機器からのセンサーデータを受け取って、特定の条件にもとづいてデータベース内に格納する、という処理が実現できました。


2回に分けて小出しにしたつもりでしたが、いずれもブログエントリとしては大作になってしまいました。ただコーディングを行うような手続きはほとんどなく、画面のドラッグ&ドロップと属性値の設定程度でこのくらいはできてしまったことになります。この手軽感を多くの人に体験してほしいと思っています。

また、この Node-RED エディタには今回紹介した以外にも色々な処理や格納、他サービスとの連携などがやはりコーディング処理を行うことなく実現できる便利なブロックが多く用意されています。機会があれば、もう少し違った Node-RED の使い方も今後紹介していこうと思っています。






























以前のブログエントリで、IBM IoT Foundations から提供されているオンライン IoT シミュレータを紹介しました:
センサー付き IoT シミュレータ


MAC アドレスを持つセンサー付き IoT デバイスがソフトウェアでシミュレートされていて、温度や湿度などの情報を任意値に変えることができ、かつ MAC アドレスを通じてそれらの値を取得することができるようになっている、というものです。

今日はこのシミュレータを使って IoT のリアルタイムアプリケーション・・・と呼んでいいのかどうか微妙ですが、IoT リアルタイムアプリケーションの前段階になるようなフローチャートを、IBM Bluemix の Node-RED サービスを使って作成する、という手順を紹介します。 前半の今回は Node-RED サービスと IoT センサーシミュレータが接続できる確認までを、次回はもう少しワークフローっぽい内容のアプリケーションを実際に作るサンプルを紹介します。


では最初に Node-RED について簡単に紹介します。Node-RED は IBM Emerging Technology が作成したオープンソースツールです。入力/出力/処理といった様々な種類のブロックを組み合わせるだけでワークフローを作ることができるツールで、その入力は各種デバイスであったりネットサービスであったり、出力結果はデータストアであったりウェブサービスであったりします。独自に開発するコードを使わない場合であれば、ほぼコーディングは不要です。Node-RED 自体は IoT 専用のツールではないのですが、IoT 向けのアプリケーションを非常に簡単に作ることができます。この辺りは「論より証拠」なので、早速使ってみましょう。


まず接続する IoT センサーシミュレータの情報を確認しておきます。「センサー付き IoT シミュレータ」にアクセスして、横スワイプで Object Temperature(機器温度)の画面に切り替えます(この画面では初期値が 24 度になっていることが確認できます)。同時に画面右上部の MAC アドレスをメモしておきます。今からこの仮想センサーの機器温度の値を取得するアプリケーションを Node-RED を使って作成します:
2015032019


Node-RED の環境を簡単に準備するために IBM Bluemix のボイラープレート(テンプレート)機能を使います。まず IBM Bluemix にログインして、「カタログ」の「ボイラープレート」カテゴリから、「Node RED Starter」を選択します。このボイラープレートを選択することで、初期データストア機能まで含めた Node-RED 環境を簡単に構築できます:
2015032001


Node-RED Starter の設定画面です。設定といっても注意すべきはアプリケーションの名前くらいです。インターネット上のホスト名として重複のない名前(この例では自分の ID を使って dotnsf-nodered という名前を指定することで重複を避けています)を入力し、「作成」ボタンをクリックします:
2015032002


Node-RED Starter ボイラープレートを使ったアプリケーションの起動が開始されます。ここで一度ダッシュボードに戻ります:
2015032003


しばらく待つとアプリケーションサーバーと各種サービスが全て起動し、作成したアプリケーション(この例では dotnsf-nodered)が「実行中」というステータスになります。この時点で Node-RED エディタが使えるようになっています:
2015032004


実際に Node-RED エディタを使ってみましょう。ダッシュボードでアプリケーションを選択後、アプリケーションが起動していることを確認したら「経路」と書かれた箇所に表示されているリンクをクリックして、Node-RED アプリケーションにアクセスします:
2015032005


このような Node-RED の初期画面が表示されるはずです。画面下部の "Go to your Node RED flow editor" と書かれたボタンをクリックします:
2015032006


Node-RED エディタ画面が表示されます。環境によっては初期状態でなんらかのブロックが画面中央のキャンバス設置されていることがあるかもしれませんが、一旦全て削除(マウスでクリックして DEL キー)して、キャンバスを空の状態にしておきます:
2015032007


ではこの状態から、IoT センサー(シミュレーター)の機器温度値を取得して表示する、というアプリケーションを作ってみます。画面左ペインの input カテゴリから "ibmiot" と書かれたブロックをドラッグ&ドロップしてキャンバス内に配置します。このブロックが「IoT 機器からの入力」と意味するブロックになります:
2015032008


"ibmiot" ブロックがキャンバス内に配置されました。同時に画面右ペインの info タブ内にこの "ibmiot" ブロックに関する属性が表示されます:
2015032009


配置された "ibmiot" ブロックをダブルクリックすると、この "ibmiot" ブロックの属性値を変更する画面が表示されます。このブロックを IoT センサーシミュレータとするために、以下の値を入力します:
 Authentication: "Quickstart"
 Input Type: "Device Event"
 Device Id: IoT センサーシミュレータに表示されていた MAC アドレス(英字は全て小文字、コロンなし)
 Name: "IoT Sensor"(表示上の名前なのでなんでも可)
最後に OK ボタンをクリックして、この編集画面を終了します。これで MAC アドレスの値が間違っていなければ、このブロックは IoT センサーシミュレータをエミュレートしていることになり、センサーの値が取得できるようになりました:
2015032010


次に画面左ペインの output カテゴリから "debug" と書かれたブロックをキャンバス内にドラッグ&ドロップします:
2015032011


続けて "ibmiot" ブロックから "debug" ブロックに向けてマウスをドラッグします:
2015032012


するとこの2つのブロックの間が線で繋がり、下図のような状態になります:
2015032013


ここで "debug" ブロックをダブルクリックして属性を確認します(以下のデフォルト値のまま変更する必要はありません、この内容になっていることを確認して OK ボタンをクリックしてください)。これでこのブロックは入力値として入ってくるデータの中の msg.payload の値を debug タブに出力する、という処理を行うブロックになりました:
2015032014


ここまでの作業でどのようなワークフローになるか、一度実行して確認してみましょう。画面右ペインを "debug" にした上で、右上の "Deploy" ボタンをクリックします:
2015032015


画面上部に "Successfully deployed" と表示されれば、このワークフローが正しくデプロイされて稼働したことを意味します:
2015032016


しばらくすると画面右ペインの "debug" タブに値が JSON テキストが2秒おきに表示されはじめます。これが IoT センサーシミュレータから得られた msg.payload の値です(d.objectTemp の値が 24 になっていることを確認してください。IoT センサーシミュレータで設定されている Object Tempreture の値と同じです):
2015032018


ではこの状態で IoT センサーシミュレータの機器温度を変更してみます。矢印ボタンを何度かクリックして機器温度を別の値に(下図では 41 度に)変更します:
2015032020


その直後から Node-RED エディタ内の debug タブに表示される値の d.objectTemp の値も 24 から 41 に変わるはずです(画面ではその途中の 36 度の時の値も表示されています):
2015032021


つまり、この Node-RED キャンバス内に配置された "ibmiot" ブロックは(MAC アドレスを指定しただけですが)IoT センサーシミュレータのデバイスをシミュレートして動いていることが分かりました。そしてこのデバイスから送られてくるセンサーからの入力値は debug ブロックによって正しく出力できていることもわかりました。

とりあえず前半はここまで。Node-RED エディタを使って IoT 機器(シミュレータ)からセンサーの値を取得して表示する、というシンプルなワークフローを作ることができました。次回はもう少し複雑なワークフロー処理を実現する予定です。

















 

このページのトップヘ