Azure + Perl でサーバレスなジョブシステムを作る
※このエントリは Microsoft Azure Advent Calendar 2016 及び Perl5 Advent Calendar 2016 の10日目のエントリです。
どーも、わいとんです。
今日はタイトルの通り、Microsoft AzureとPerlでサーバレスなジョブシステムを作るまでの流れを紹介していきます。
Azure 及び Perl について
その前に、このエントリにはAzure及びPerl双方の大まかな知識があることと、手元の端末がMacOSXであることが前提になります。
念のため、それぞれざっくりした説明をしておきます(多分に私見が混じっておりますことをあらかじめご了承ください)。
Azure とは
Microsoft Azure(以下Azure)はMicrosoft社がサービス提供をしているクラウドサービスです。
仮想マシンやネットワークなどをはじめとしたIaaS、Web Appsを軸にしたPaaS、そしてMobile AppsやNotification HubsなどのSaaSが提供されており、近年Amazon Web ServicesやGoogle Cloud Platformと並んで、クラウド御三家 などと例えられたりします(主に僕が例えてます)。
Microsoftのサービスらしく、基盤技術としてはWindowsや.NET技術が中心となっていますが、同社は最近OSSへのコミットメントが大変著しく、AzureでもLinuxのサポートが行なわれているサービスが結構存在します。
なお当エントリは、既にMicrosoftアカウントをお持ちで、Azure Portalでのサービス操作が可能なことが前提となっています。また、各種費用については事前に料金計算ツールなどでご確認の上、ご自身の責任においてお試しください。
Perl とは
1987年にLarry Wall(ラリー・ウォール)によって公開されたスクリプト言語です。
今日LL(Lightweight Language)と呼ばれるプログラミング言語群の先駆けであり、過去にはCGIというWebアプリケーション提供手法と組み合わせたパラダイムで一世を風靡しましたが、ここ最近はPHPやRubyなどの登場により、シェアは漸減しているようです。
しかしながら、CPANを軸にしたエコシステムの存在によって拡張性が大変強力であり、かつ徹底した後方互換性の維持方針によって、古いソースコードでも安定稼働が期待できます。
近年はテストドリブンな開発手法や継続テストなどによるモダンかつ安定性を重視した開発手法が採用されることもあり、当エントリも「モダンな手法としてのサーバレスアーキテクチャ」をPerlで実現する、というところを重視したつもりです。
Azure上に環境を作る
前置きが長くなりましたが、ここからはスナップショット画像を交えて、Azure上への環境構築の様子を解説していきます。
リソースグループを作る
Azure Portal上で新しくリソースグループを作ります。
※リソースグループとは: Azureにある様々なサービスを、用途ごとにまとめておく枠組みです。詳しくはこちらのエントリを参照してください。
画面左側にある水色の立方体アイコンがあるので、これをクリックすると、リソースグループ一覧が表示されます。そこに「追加」というボタンがあるので押すと、リソースグループ名の入力とロケーションの選択を促されます。
これらの入力を終えて作成ボタンを押して少し待つと、以下のようにリソースグループの概要が示されます。
これでリソースグループの完成です。
Event Hubsをデプロイする
リソースグループの概要画面で「追加」ボタンを押すと、デプロイしたいサービスを選んだり検索できる画面になります。ここでは「event hubs」と検索窓に入力してあげると、以下のようにEvent Hubsが登場しますので、これを選択します。
すると、以下のように概要説明が出てきますので、作成ボタンを押します。
作成ボタンを押すと、以下のように料金体系の選択や名称の設定など、5項目について入力を求められます。
なお、今回僕は以下のように設定しました(なんかでかいかも)。
デプロイには数分かかることもあるので、コーヒーでも淹れながらのんびり待っていると良いかと思います。そのうち以下のような通知がベルマークのところに出てくるので、待ちましょう。
デプロイが完了してからリソースグループの更新を行うと、以下のようにEvent Hubsがデプロイされていることが確認できます。
Event HubsにHubを追加する
続いて、実際にペイロードの受容部となるHubを追加します。
先ほど作成したEvent Hubsを選択すると、以下のような画面になりますので、「+Event Hub」ボタンを押します。
すると、以下のように設定項目が登場しますので、NameとPartition Count(今回は8にしました)を適宜設定し、Createボタンを押します。
少し待つと、Event Hub作成完了通知が以下のように出てきます。
これでHubの追加が完了しました。
追加したHubにSAS鍵を追加する
実際にHubに対してペイロードを受容してもらうためには、あらかじめ定められた鍵を以ってペイロードの送信を行う必要があります。この鍵を使ったやりとりのことをSAS(Shared Access Signature)と呼びます。
鍵を作るには、先ほど追加したHubの概要を開きます。下記の例では 「Event Hubs」をメニューから選択し、一番下の方にちらっと見えている「advent」という名のHubを選択する感じになります。
すると以下のような画面が出てきますので、メニューから「Shared Access Policy」(鍵マークのやつ)を選択します。
最初は見ての通りShared Access Policyが何も存在しません。ポリシーを新しく作る必要があるので、「Add」ボタンを押します。
新規作成するポリシーの名称及び権限設定(Claim)を要求されます。
名前は任意の文字列、権限は「Manage」を設定して「Create」ボタンを押すと、ポリシーが作成されます。
中身を見てみると、以下のように権限設定の確認、それと鍵と接続文字列がそれぞれPrimary, Secondaryと並んでいます。
とりあえず後で使うので、接続文字列を(Primary/Secondaryどちらでもいいので)コピーして、どこかにメモしておいてください。
Function Appをデプロイする
Event Hubsの準備ができたところで、次にFunction Appsの準備を進めます。
改めてリソースグループの概要に戻り、「追加」ボタンを押して「function app」と検索窓に入力します。すると、Function App が検索結果の一番上に出てくるので、これを選びます。
以下のように解説が出てきますが、とりあえず「作成」ボタンを押します。
設定を要求するブレードが登場しますので、以下の例を参考に各々埋めて「作成」ボタンを押してください。
しばらく待っているとデプロイが完了しますので、リソースグループの概要で「更新」ボタンを押すと、以下のように稲妻アイコンのApp Serviceが登場しています。これがFunction Appです。また、ストレージアカウントも一緒に作られます。
Function Appに関数を追加する
早速、出来上がったFunction Appを見てみると、以下のようにデカデカと関数への早道と書かれた仰々しい画面が登場しますが、これはどうでもいいです。
とりあえずデカイやつはどうでもよくて、左側のメニューにある「新しい関数」を選択します。すると以下のように「テンプレートの選択」が登場します。
ここでいろんなテンプレートがあって目移りするかもしれませんが、僕としては男は黙ってBashという信条がございます故、言語にBashを選択します。
すると・・・
悲しいかな、選べるものが1つしかなく、しかも「Azure Queue Storage」をトリガーとした関数テンプレートしかないのです。
しかし!ここで諦めてはいけない! まず、そのままこのテンプレートを選択します。
すると、選択したテンプレートの下に以下のようなフォーム群が登場します。とりあえず関数名を簡単なものにして、そのまま「作成」ボタンを押してください。
これでとりあえず関数がデプロイされました。ただ、このままではEvent Hubsとの連携ができていませんので、この後直していきます。
追加した関数の入力元にEvent Hubsを指定する
さて、出来上がった関数は以下のようになっています。
なるほど。シンプルですね。
次に、左側のメニューから「統合」を選択します。
先ほどのテンプレート設定みたいな画面が出てきましたが、右上にある「詳細エディター」を選択してください。
詳細エディターというのは、トリガーや入出力をJSON形式で自力で設定するためのツールなのですが、ここで以下のように修正し、保存します。
変更した箇所は "type"
の設定値が "queueTrigger"
だったのを "eventHubTrigger"
に変えただけです。
この状態で「標準エディタ」を選択すると・・・
トリガーの部分が「Azure Queue Storage」から「Azure イベント ハブ」に変わっていますね!
Event Hub接続をFunctions Appに設定する
今度は「イベント ハブ接続」の設定を行うため、上気した画面の右下にある「新規」リンクを選択します。すると下記のような画面になります。
最初は「結果はありません」と書かれていますね。その上にある「接続文字列の追加」を押してください。
接続名は任意の文字列隣ます。、接続文字列ですが、ここで先ほどコピーしておいたEvent Hubの接続文字列を貼り付けます。
ここまでやったら「OK」ボタンを押します。
ご覧の通り、イベントハブ接続の設定ができました。
クライアント側の実装を作る
さて、ここまででようやくAzure側の設定が完了しました。あとはクライアント側のコード実装を行い、ペイロードを投げ込むだけです。
ところで皆さん、PerlでEventHubsにペイロードを送信するための方法をご存知でしょうか?
おそらくほとんどの方はご存知ないと思いますが、Net::Azure::EventHubsというモジュールがCPANにリリースされていて、これを使うと簡単にEventHubsにペイロードを送信することができます。なお、Net::Azure::EventHubsを作ったのは 僕 です。
Net::Azure::EventHubsを導入する
それでは cpanm あるいは cpm を使ってNet::Azure::EventHubsをインストールしてみましょう。
cpanmの場合
$ sudo cpanm Net::Azure::EventHubs
cpmの場合
$ sudo cpm install -g Net::Azure::EventHubs
これでインストールに成功すると思います。
スクリプトを書く
では実際にペイロードを送信するプログラムを書いてみます。
use strict;
use warnings;
use Net::Azure::EventHubs;
my $hub = Net::Azure::EventHubs->new(
connection_string => 'Endpoint=sb://...',
);
my $req = $hub->message({
name => 'ytnobody',
age => '36',
fav => [qw/Gyoza Curry Lucky-Pierrot/],
});
$req->do;
※ connection_string
はご自身の環境に合わせて変更してください。
実際にペイロードを送信してみる
これをbashで実行すると、下記のgifのようになります。
ウル技(ウルテク)
さらにもう一歩Perlを推し進めたウル技を披露します。
Function AppでPerlを使ってペイロードを処理する
Azure側の関数のコードを以下のようにすることで、関数記述言語として、なんとPerl(v5.22.0)が利用可能です!!!!
まず run.sh
は以下のように。
そして新しく worker.pl
を作り、以下のようなコードにします。
非常に簡単なコードですね。これは run.sh
で受けたペイロードをそのまま worker.pl
に横流しして、そのままデバッグログに出力するだけの仕組みです。
これを動かすと、こうなります・・・!
Azure Function AppはPerlが動くぞ!すごい!!
まとめ
- AzureとPerlは協調できる!
- Net::Azure::EventHubs を作ったぞ!
- Azure Function App はPerlも使えるぞ!
最後に
このエントリは YAPC::Hokkaido 2016 SAPPORO に参加しながら執筆しました。次回のYAPC::Japanは関西での開催らしいです。