※当記事でご紹介しているAzure Functionは、執筆時(2016年10月)当時はプレビュー版でしたが、2017年1月現在は正式版となっています。 Event Hubのデータをリアルタイムに処理してデータベースへ登録する仕組みを Azure Functionsを利用して作ってみました。
Azure Functionsを選択した理由は Event Hubのデータと連動して動作するという仕組みを簡単に実装できそうだったのと Javascriptのみで完結するという点でお手軽そうかなと思った為。
実際、(途中で発生した問題を除いて)簡単にできました。
似たようなことが出来るサービスとしてStream Analyticsというものもあり こちらはコードの記述なしに各出力先にデータを放り込めます。 (Transact SQLのような記載でデータの振り分けなんかも可能)
データを受け取ってからデータを書き込むまでにロジックが必要ならFunctions、 ロジックが必要ないのならStream Analytics というような選択になりそうです。
Azure Functionsは現在プレビュー中の機能で、頻繁にアップデートされており 触ってる間にも次々アップデートされて大分改善されてきました。
こちらのブログに乗せているスクリーンショットは後から画面キャプチャしたので 現在の最新版(バージョン0.6)のものになりますが 実際に試していたのはバージョン0.5のころです。
Azure Functionsを実際に触ってみた
こちらから、Event Hubと連携するテンプレートが選択できます。 (標準のところからは選べないので、赤枠のカスタム関数から選択します)
ここでEventHubTrigger – Nodeを選択します。
イベント ハブ名に接続するイベントハブの名前を入力 イベント ハブ接続の横の新規をクリックして、イベントハブの接続文字列を設定してやります。
すべて入力し、作成を押すとFunctionが作成され、接続準備完了。 こんな画面が表示され、コードもそのまま記述できます。
また、少しスクロールしてやると Event Hub等と実際に連携しなくてもデバッグ出来るように 直接Functionにデータを投げてやるようなインターフェースもあります。
実際にEvent Hubに向けてデータを投げてやるとちゃんと連携して動作します。 上手くいっていれば、デバッグ時と同じように以下のような内容のログが流れます。 (Test Eventという部分が実際にEvent Hubに投げたデータです)
2016-10-03T11:09:51.948 Node.js eventhub trigger function processed work item Test Event 2016-10-03T11:09:51.948 Function completed (Success, Id=94e5274e-94a2-442a-b7a9-76f3735ed8b9)
出力の設定
続いて出力先の設定。 現在のバージョンでは、SQL Databeseをアウトプットとする設定はテンプレートとしては選択できませんが Function Appで実装するスプリクト内でデータベースへ接続する分には問題なくできます。
楽に接続できるサービスはこんな感じ。
データベースへのアクセスへは、tediousというライブラリを使用します。 https://msdn.microsoft.com/library/mt715784.aspx
正式版ではSQL Databaseへも簡単につなげるといいですね。 Azure Functionsは現在プレビュー中の機能で、頻繁にアップデートされていますので、今後に期待です。
Azure Functionsでライブラリを使いたい場合ですが、kuduというコンソール画面を使うと便利です。 こちらのメニューから
kuduを選ぶとこんな感じ。
Unix風のインターフェースが出ますが、Windowsらしい。
ここで site -> wwwrootと辿っていくと先ほど自分で作ったFunctionがあるので そのフォルダに入って
> npm install tedious
と実行すると、tediousがインストールされ Functionでtediousが使えるようになります。
こんな感じに引き込めます。
var Connection = require('tedious').Connection;
var Request = require('tedious').Request;
var TYPES = require('tedious').TYPES;
// データベースへの接続設定をoptionに設定
var option = { userName : ‘userName’, password : ‘password’, server : ‘server’, options : { encrypt : true, database : ‘database’ } }
module.exports = function (context, myEventHubTrigger) {
context.log(‘Node.js eventhub trigger function processed work item’, myEventHubTrigger);
var dbConnection = new Connection(option);
dbConnection.on(‘connect’, function(err) {
request = new Request(“INSERT TestTable (data) VALUES (‘” + myEventHubTrigger + “‘)”, function (err, rowCount) {
if (err) {
context.log(err);
} else {
context.log(rowCount + ‘ rows’);
}
context.done();
});
dbConnection.execSql(request);
});
};
で、Event Hubに向けてデータを投げてみると・・・、上手くいったっぽい。
2016-10-03T11:42:54.204 Node.js eventhub trigger function processed work item TEST 2016-10-03T11:42:54.392 1 rows 2016-10-03T11:42:54.392 Function completed (Success, Id=03375413-0c6c-4cfe-a45f-a7dd7efc3f7a)
手元でも確認して見てもちゃんとDBにも反映されていますね。
SELECT * FROM TestTable; key data — —- 1 TEST
1 row(s) returned
余談ですが…
実は一通り実装しうまく動作することを確認するも しばらくするとデータベースへの接続が上手くいかない問題が発生し 長らく頓挫していました。
色々調べてみるも結局わからず、Azureのサポートに駆け込みました。
プレビュー版ということで正式サポート外だったのですが Azureのサポートの方に非常に丁寧に対応頂いて助かりました。
結果的には試していたバージョン0.5でのバグでした。 最近リリースされたバージョン0.6では解消しています。
バージョンアップはこちらから手動で行う必要があります。