freedom-man.com

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

Category: AWS (page 2 of 4)

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の生存確認が可能になり、

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

ApexからSWFを触ってみる【ワークフローの終了まで】

前回はActivityTaskの登録までやったので、今回はワークフローの終了までやります!

※REST APIの基本的な部分は端折っているので、詳細な部分を知りたい方は過去記事をご参考ください!

 

4. Activity Taskの取得(PollForActivityTask)

実行ActorはWorkerになります。

Activity TaskListに投げられたActivity Taskを取得します。

 

 

■主要パラメータの説明

identity

→どのWorkerが取得しようとしているかを明示する。ワークフロー履歴でTaskを取得したWorkerを特定するためのパラメータ。

taskList

→取得先のActivity TaskListを指定。3(ActivityTaskのスケジュール)と同じTask Listを設定すれば、

3で投げたワークフローのDecision Taskを取得可能。

 

レスポンスは以下のとおり

 

Decision Taskと違って、ワークフロー実行履歴は取得できませんが、

代わりにactivityTypeとinputパラメータ値からWorkerの動作を決めることができます。

taskTokenは5でSWFに通知する際に使用するトークンです。

 

5. Workerがタスクを実行し、DecisionTaskを登録(RespondActivityTaskCompleted)

実行ActorはWorkerになります。

4で取得したActivity Taskに応じてWorkerがタスクを実行し、完了後にSWFに通知をします。

これにより、次のDecision Taskがスケジュールされます。

 

 

■主要パラメータの説明

result

→タスクの処理結果を入力。この結果は後続のDeciderが参照可能。

taskToken

→4のレスポンスで取得したtaskTokenを入力。

 

レスポンスは空になります。

 

6. 2~5を繰り返して、ワークフローを進める

DeciderがDecisionTaskを取得

→DeciderがActivityTaskを登録

→WorkerがActivityTaskを取得

→WorkerがSWFにTask終了の通知

→SWFがDecisionTaskを登録

というフローを繰り返します。

 

7. Deciderがワークフロー終了条件を満たしたと判断した場合、ワークフローを終了する

実行ActorはDeciderになります。

DeciderはPollForDecisionTaskでタスクを取得後、SWFに対してワークフローの終了通知をします。

 

 

■主要パラメータの説明

decisionType

→Decisionの種別。ワークフローの終了通知なので”CompleteWorkflowExecution”を指定。

result

→SWFに通知する処理結果。

 

レスポンスは空になります。

 

 

今回は正常系フローの説明だったので5ではActivityTaskの完了通知をしていましたが、

ActivityTaskの失敗を通知したり(RespondActivityTaskFailed)

ActivityTaskの実行をキャンセルしたり(RespondActivityTaskCanceled)

Activity実行中であることを通知したり(RecordActivityTaskHeartbeat)

SWFに様々な通知をすることで、柔軟なワークフローを構成することができます。

 

次回は実際のフローとイベント登録に関して説明する予定です!

Older posts Newer posts

© 2018 freedom-man.com

Theme by Anders NorenUp ↑