freedom-man.com

ブログは俺のセーブポイント

Category: AWS (page 2 of 5)

ApexからAmazon Lambda叩いてみる。

Amazon Lambdaというすんばらしいサービスがプレビュー提供されたということでApexから触ってみた。

 

1. Lambda側のfunctionを書く

今回はChatter投稿するようなスクリプトを書いてみた。

上記スクリプトをindex.jsとして保存する。

必要なパッケージもローカルインストールしておく。今回はjsforceのみ。

2. 作成したLambda functionをアップロードする

node_modulesと対象のスクリプトファイルをまとめてzipファイルにする。

で、アップロードする。

AWS Lambda

Function Name, Description→適当に

Function Code→生成したZipファイルをアップロード。File nameとHandler nameはそのまま。

Role name→Functionの実行コンテキストになるロールを指定する。Create/Select Roleで作成・指定すればOK。

Advanced Settings→一回あたりのFunction実行の利用可能なメモリやタイムアウト時間を適当にセット。

3. 動作確認

作成したLambda Functionが正しく動作するかを確認する。

まずは確認対象のLambda Functionを選択してEdit/Testをクリック。

lambda_select

Customを選択して適当なJSONをセットしてInvokeをクリック

AWS Lambda_Test

下の方のExecution resultsにログが出るので確認。

lambda_test

日本語が???とかに文字化けてますが、CloudWatch側のログにはちゃんと残ってます。

CloudWatchで見る場合はLogsから対象のFunctionを選択して掘り下げていくとログが見れます。

lambda_log_list

lambda_log

4. Lambdaを呼び出すApexクラスを作成

現時点ではLambdaのドキュメントにはREST APIの仕様があまり書かれていないっぽくて

Signature Versionがどれに対応しているかとかよくわからなかったんですが、

JavascriptのSDK見たらSignatureのVersion指定のパラメータで

v2,v3,v4が指定できる的なことが書いてあったのでv4で実装してみたら、普通に呼び出せました!

Signature Version4での生成方法はこちら

 

で、いつも通り汚い感じですが、Apexで書くとこんな感じ↓

ApexでのSignature Version4の生成方法は過去の記事を参照ください!

リモートサイトの設定も忘れずに。

lambda_remotesite

あとは普通に呼び出すだけ!

で、Chatterを開くと…

lambda_chatter

Good!!

 

今回のサンプルだとApex→Lambda→Chatterというフローになっていて

Lambda経由のChatter投稿という意味なさげな感じになっていますが

実際にSalesforceで連携するときのユースケースとしては

S3にアップロードされたらChatterFeed作ってあげたり、他のSFDCのAPIを叩いたり

ApexトリガでDML走る度にLambda function動かすとか、そういった使い方になると思います。

 

一日しか触ってないですが、サーバ立てたりオートスケールの設定無しで

スケールするファンクションを簡単に作れるのは、非常に強力だなーと思いました。

ApexからAutoScaling触ってみる。

今回はAuto ScalingをApexからREST APIで触ってみます。

 

Auto Scalingは指定したインスタンスが落ちたら自動的に指定のインスタンス数になるまで

同じインスタンスを立ててくれたり、指定した時刻にインスタンスを動的に増減させることのできる

自動でスケーリングをしてくれるサービスです。(って名前そのまんまの説明…)

 

これを使うと、

「毎週日曜日は負荷が高いから自動的に処理をするインスタンス数を増やそう!」とか

「万が一インスタンスが落ちてもすぐにインスタンスを立ち上げるようにしよう!」とか

「不健全なインスタンスを落として健全なインスタンスだけ生かしたい!」とか

こういったスケールアウト、スケールインが自由自在にできちゃいます。

 

前回はEC2をREST APIを使って手動で立ち上げていて、

”EC2のREST APIを使ってスケジュール化するためにはApexバッチが必要”と書きましたが、

このAuto Scalingを使えばスケールアウトを自動化できるので

インスタンス数を0→1にスケールアウトするようなスケジューリングをAuto ScalingをCUIとかで

一回設定してあげれば自動インスタンス起動の処理ができちゃいます。

 

Auto Scalingのスケジューリングに関する参考URL↓

http://dev.classmethod.jp/cloud/auto-scaling-schedule/

http://blog.suz-lab.com/2012/04/ec2.html

 

また、Auto Scalingを利用しない単純なEC2インスタンス起動は、立ち上げた後は負荷が高かろうが

インスタンスが落ちようが、別のAPIでチェックしない限りは検知することができないのと

検知しても自動的にスケールさせたり、落ちた時に自動的にインスタンスを立ち上げるという

仕組みを自前で実装しなければなりません。

 

そこで、Auto Scalingの出番ということです!

 

ということで、今回のサンプル!↓

Auto ScalingはSignature Version2Version4の両方が使えるんですが、

Version4を推奨、とリファレンスに書いてあったので素直に4でやってます。

Signature Version4はDynamoDBのときにやっていたので、大枠はその回のコピペです。

 

っていうかやっぱりVersion4は複雑…。

ちゃんと間違っていたらResponseで答えを教えてくれるんで、正解にはたどり着きやすいんですけどねー。

(ちなみにSWFはResponseで答え教えてくれないっていう)

 

メソッドはupdateAutoScalingGroupしか無いですが、

SalesforceからコールするAPIとしてはこれで十分かと思われます。

 

基本的にはconsole GUIやCUIであらかじめ作成・スケジュール設定をした

launch configulationやauto scaling groupに対して

Salesforceはauto scaling groupの更新でインスタンスの増減をコントロールする運用を想定していて、

ワンタイムの設定のためにSalesforceでわざわざAPIを叩くのはあまり意味が無い気がするからです。

ApexからEC2を触ってみる。

恒例の触ってみるシリーズ、今回はAWSの大黒柱(だと勝手に思っている)EC2です!

 

SalesforceでEC2を触ることのモチベーションの一つとしては

「Apexでは不可能な処理をEC2を一時的に立てて処理を行わせる」ということ。

 

例えば、Salesforceの全データをバックアップする!といったバッチ処理の場合は

force.com内部で行わせるよりは別サーバからデータローダCLI等のAPI経由でやってもらった方が

ガバナ制限から開放される上に、プログラミング言語がサポートする範囲の

自由な形式でデータを出力することができます。

しかし、常時稼働のサーバを立ててしまうとコストが大きいため

こういったデータバックアップのような処理はバッチ実行時のみのスポット稼働が求められます。

 

そこでEC2の出番ということです!

 

ということで今回のサンプル↓

 

REST APIのリファレンスはこちらから。

Signature Version2なのでSignature生成はSimpleDBのコードのコピペです。

 

また、例としてはインスタンスのスタートとストップだけですが、

Salesforceで利用することを考えるとこれで十分な気がします。

 

Salesforceの利用フローとしては以下のようなイメージ

1. Salesforceからインスタンスを立ち上げ(Start)。

2. EC2でバッチ実行(/etc/init.d内に起動スクリプト置いたり、cron実行させたり)

3. バッチ終了時にEC2内のスクリプトでシャットダウン(shutdownコマンド使うか、インスタンスStopのAPIを叩く)

※shutdown時の振る舞いがterminateになっているとshutdownするとインスタンスが消えるので注意

 

Apexバッチを使用すれば、スケジューリングされた自動バッチ処理ができます。

さらに、AWSのAuto Scalingを使えばApexバッチを利用すること無く自動バッチ処理ができます。

 

ということで、次回はAuto Scaling!

 

SalesforceとSWFの連携【机上の空論編】

さて、これまでApexからSWFと連携させてきましたが、

SalesforceとSWFの連携のユースケースについて自由気ままに考えてみます!

※今回はSWFについてあーだこーだ言う回です。特にまとまっていません。

SWFでシステムを実装したことないので机上の空論です。

ということで、ところどころ、おかしいところがあるかもしれませんが、ご容赦くださいm(_ _)m

 

1. Salesforce内部から外部Webサービスの利用

ApexからのHTTPコールアウトはガバナ制限があり、

1トランザクション当たりの長時間のコールアウトの対応が難しい。

※2014/02時点では1トランザクション当たりの合計時間が120秒以内の制限値。

 

そこで、長時間のコールアウトになる場合、つまり時間がかかるようなタスク処理をさせるには

HTTPリクエストに対する応答は即座に返し、タスク処理を非同期で実行するような仕組みが必要になる。

この非同期実行処理はSWFが適しており、

ApexからのHTTPリクエストはSWFに対してStartWorkflowExecutionを実行し、

処理を実行するDecider、Workerは処理を実行するサーバ側に立ててあげれば容易に実現できる。

非同期処理自体はSWF等のクラウドキューサービスがなくてもWorker上に実装できるが、

SWFを利用する方がスケールアウトしやすく再利用性が向上する。

 

ただし、タスク処理自体が同期実行でなければならない場合は、基本的にはSWFは適さない。

 

2. 外部WebサービスからSalesforceを利用する場合

外部WebサービスからSalesforceのデータを利用する場合は

a. Salesforceのデータを画面表示するような即時利用パターン

b. Salesforceのデータを別サーバDBに連携するパターン

c. 別サーバのデータをSalesforceに連携するパターン

の3パターンが考えられる。

 

a のような即時利用パターンではSWFのような非同期処理は向いていないので適用不可能。

この場合は素直にforce.com canvasとか使ってAPI使っでやるのが吉かと。

 

b では連携したいSalesforceレコードを、Salesforce側からSWFに投げてもらい

別サーバがWorkerとしてそのデータを受け取り、タスク処理(連携処理)を実行する方法が考えられる。

Salesforceではアウトバウンドメッセージという外部連携用の標準機能が存在するが、

疎結合のメリットを活かすのであれば、エンドポイントを共通化出来るSWFを利用した方法が良い気がする。

 

c では別サーバ側が作成・更新したいレコード情報をSWFに投げて、

そのデータをforce.comのApexスケジューラで拾わせてApexクラス側で作成・更新処理を行う。

単なるデータ同期だけでなく、Webフォームで入力されたデータをSWFを介して

Workerに処理させることができるので、連携先プラットフォームに変更があっても

送信元プログラムの変更がないことが利点。

 

Salesforceへの連携をする上でSWFを利用する共通のメリットとしては、APIコール数を消費しないということ。

デメリットとしてはSalesforceをWorkerやDeciderとして動作させるためにはApexスケジューラを利用する必要があり、

一日あたりのスケジュール実行数等の制限値・ガバナを考慮する必要があるということ。

 

また、cのパターンでWebフォームからの連携を考える場合、エラー時は同期実行、つまり即時でエラーを

エンドユーザに知らせる必要があるので非同期になるSWFでは適していない。

エラーハンドリングをWeb側で独自で行ってしまうと、

入力規則等のSalesforceのカスタマイザブルなビジネスロジックの構築というメリットを損ねてしまう上に

バリデーション系はモデルに実装すべきというMVCモデルの理想からも離れてしまう。

 

また、経験的にAPIコール数も上限を越えるケースがあまり無く、

上限もオプション(追加料金)である程度解決できたりするから

2のパターンにおけるメリットは全体的に微妙かな~とも思ったり。

 

 

結局のところ、疎結合・非同期処理と密結合・同期処理という2つの相反する特性を把握した上で

SWFを利用するか従来型のAPI連携をするかを判断をすべきかと。

密結合なシステムでも比較的小さなシステムであればそこまで大きな問題にはならない気がする。

一番大切なのはちゃんと動くシステム。その次に保守性。って感じ?

 

スケールアウトと再利用性は比較的大きいシステムでこそ大きな力を発揮できるものなのかな~思う。

 

あと、SWFの基本概念を学んだ印象としては、

「疎結合・非同期なシステムを作るにはとてもよいサービス」である一方で

「AWSの中では比較的学習コストが高く、疎結合ワークフローが故に実装時の考慮事項が多い」

というデメリットも感じたので、ここまで書いて何だけど、なかなか実戦投入は難しそう…。

AWSのSWFについて書いてみる【補足編】

前回まではApex(force.com)でSWFを触ってみましたが、今回はSWFに関する補足説明をしていきます!

 

【イベント登録に関する補足】

それぞれのActorがSWFに通知を行うことでワークフローが進むというのが

SWFのおおまかな構造になっていますが、通知を行う毎にワークフロー上には

イベントが登録されていきます。

 

イベント登録の流れについては正常系フローに沿って書くと以下のようになります。

1. ワークフローのスタート

StartWorkflowExecutionを実行すると、

WorkflowExecutionStarted、DecisionTaskScheduledの2つのイベントが登録されます。

StartWorkflowExecution

 

2. Decision Taskの取得

PollForDecisionTaskを実行すると、スケジュールされたDecisionTaskがDeciderによって取得され

DecisionTaskStartedのイベントが登録されます。

PollForDecisionTask

 

3. Decision&ActivityTaskの登録

RespondDecisionTaskCompleted(ScheduleActivityTaskDecision)を実行すると、

DecisionTaskCompleted、ActivityTaskScheduledのイベントが登録されます。

ScheduleActivityTaskDecision

 

4. Activity Taskの取得

PollActivityTaskを実行すると、Deciderによって登録されたActivityTaskが

Workerによって取得され、ActivityTaskStartedイベントが登録されます。

PollActivityTask

 

5. ActivityTaskの実行&完了通知(DecisionTaskの登録)

RespondActicityTaskCompletedを実行すると、

ActivityTaskCompleted、DecisionTaskScheduledイベントが登録されます。

RespondActicityTaskCompleted

 

7. ワークフローの終了通知

CompleteWorkflowExecutionを実行すると、

DecisionTaskCompleted、WorkflowExecutionCompletedイベントが登録されます。

CompleteWorkflowExecution

 

 【各種タイムアウトに関する補足】

タイムアウトは以下の種類があり、WorkflowTypeやActivityType側で

それぞれ、デフォルト値を設定することができます。

 

a. ワークフロー本体の開始から終了までの時間(Execution Start to Close timeout)

b. DecisionTask取得からDecisionTask完了通知までの時間(Task Start to Close timeout)

c. ActivityTask登録からActivityTask開始までの時間(Schedule to Start timeout)

d. ActivityTask取得からActivityTask完了までの時間(Start to Close timeout)

e. ActivityTask登録からActivityTask完了までの時間(Schedule to Close timeout)

f. WorkerのHeartbeatの時間間隔(Activity Task Heartbeat)

 

a~bはWorkflowType側でデフォルト値を設定し、

c~fはActivityType側でデフォルト値を設定。

 

e はタイムアウトの性質上[ e ≦ c + d]となるように設定。

f のHeartbeatとはWorkerが長時間のタスク処理をするときに

”ちゃんと作業しているよ!”っていう報告をさせるメカニズムで、これによって「ちゃんと仕事をしているのか」と

「サーバやWorkerアプリが落ちて作業できない状況なのか」等を判別することが可能になる。

要はSWF版の報連相ってとこですねw

進捗率をHeartbeatで報告させて、画面表示させるということもできるっぽい。

短時間で終わるようなタスクの場合は必要のないパラメータ値。

 

タイムアウトに関する詳細はリファレンスに書いてあるので、そちらを参照ください。

 

ここらへんのタイムアウト値の設定でDeciderやWorkerの生存確認が可能になり、

ワークフローの実行精度を上げることが出来るっぽいです。

Older posts Newer posts

© 2019 freedom-man.com

Theme by Anders NorenUp ↑