freedom-man.com

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

Tag: swf

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に様々な通知をすることで、柔軟なワークフローを構成することができます。

 

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

ApexからSWFを触ってみる【ActivityTaskのスケジュールまで】

前回はREST APIのSignature生成とAPIコールの基本的なところを説明したので、今回は実際にSWFをApexから触ってみます!

Continue reading

AWSのSWFについて書いてみる【概要と用語編】

最近、疎結合なシステム構築のためのサービスであるAWSのSQSSWFに興味を持ったので触ってみた。

 

SQSは何でも色々できるけど、プログラムで制御しないと正常に動作しない部分が多くて、

SWFは疎結合なシステムをSQSより簡単に(?)構築できるらしい。(参考URLはこちら

ということで、今回はSWFのお話。

 

といっても、私自身SWFを利用してのシステム構築は残念ながらまだない上に

SWFのお勉強3日目くらいのドシロートで、これから書く記事は机上の空論だったり、

そもそも誤った解釈があるかもしれませんが、そこらへんはご容赦を。

というかご指摘いただくと泣いて喜びます。

 

最後にSWFの用語をずらずらーっと並べて書いたのでそちらもご覧くださいませ。

 

で、SWFの話ですが、以下のリンク先のように既に色々と解説されているので、

まずはそちらをご覧頂いたほうが理解が早いかもw

http://dev.classmethod.jp/cloud/aws/introduction-to-amazon-simple-workflow-service/
http://www.slideshare.net/AmazonWebServicesJapan/20130424-aws-meisterregenerateswfpublic

 

簡単に言うとSWFはワークフローの各タスクを疎結合にするための仕組みを提供するサービス。

 

SWFではTaskList(キュー)に各々のタスクをスケジュールし、

タスク処理をするアプリ(Activity Worker)やビジネスロジックを制御するアプリ(Decider)が

それぞれのTaskListにポーリングを行い、各々のタスクを取得後、処理結果を登録し、

次のタスクをスケジューリングするという流れでワークフローの処理を進めていく仕組みになっている。

 

具体的には

1. Starterがワークフローをスタート&Decision Task(Decider用のタスク)のスケジュール

2. DeciderがTaskListにポーリングしてタスクを取得

3. 2のDeciderが過去のタスクの実行履歴を参照して、Activity Task(Activity Worker用のタスク)をスケジュール

4. Activity WorkerがTaskListにポーリングしてタスクを取得

5. 4のActivity Workerがタスク情報を参照して、タスクを実行し、Decision Taskをスケジュール

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

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

というようなフローになる。

 

SWFが提供しているTaskListを介することで、各々のWorker(アプリ)が

SWFと密結合になるものの、Worker同士は疎結合になる。

 

疎結合になると再利用性や、スケーラビリティが向上する上に

SWFがTaskListというキューのみを提供しているという特性上、

HTTP接続が出来れば、SWFを利用するデバイスの種類や場所(クラウドかオンプレか)を問わないので

より柔軟な構成にしやすい。

 

また、別ワークフローへのコンポーネント再利用やスケールアウトは

EC2のAMIを使ってサーバーの複製が簡単にできるため、SWFはEC2と相性が良かったりする。

 

設計例として、あるシステムから他の外部システムにPDF生成処理を要求するワークフローを考えてみる。

 

PDF生成処理システムが公開しているAPIを介してリクエストを送る設計だと、

PDF生成処理システムをスケールアウトする場合には

生成要求(HTTPコールアウト)に対してロードバランサーやリバースプロキシで

処理を振り分ける設計にする必要がある。

 

さらに、PDF生成処理システムのAPIエンドポイントが変わったり、

“要求前に要求内容を上長が確認する”等のビジネスロジックの変更があると

要求元のプログラムを変更しなければならない。

 

これはビジネスロジックや結合先システムに依存してしまう

密結合なシステムになっていることに起因している。

 

これをSWFを介して連携するように実装をすると

・スケールアップ

→コールアウト先はSWFになり変更の必要がない。

また、PDF生成の要求内容(タスク)は要求先システムによるポーリングで取得されるため

ポーリング&タスク処理を行うサーバーを単純に複製しても正常に動く(スケールアウトが容易)。

 

・APIエンドポイントの変更

→要求先のシステムに依存しないため、変更の必要がない。(SWFがエンドポイント)

 

・ビジネスロジックの変更

→要求後に行う処理はDeciderが決定する為、Deciderのプログラムを新しいビジネスロジックに変更すれば良く、

要求元、要求先プログラムの変更の必要がない。

 

といったように、疎結合の恩恵が得られる。

またこういった疎結合なシステム構築により並列・結合処理を実装することも容易になる。

その場合も、ビジネスロジックを制御するDecider側プログラムの修正のみになるため

既存のタスク処理を変更する必要がない。

 

ちなみにSWFコンソールで実行できるサンプルプログラムは

1つのEC2インスタンスがStarter, Decider, Activity Workerを兼任していて、

さらに1つのWorkflowに対する全てのActivity Taskを非同期的に処理する形式になっている。

 

この1つのインスタンスで全てのActorをこなすような構成でも

プログラムタスク自体は疎結合で、ビジネスロジック変更があっても

deciderの変更のみで対応可能になる。

 

要件によってはStarter, Decider, Activity Workerは別のサーバにしたり

負荷の高いタスクがある場合は、そのタスクの処理のみを行うWorker(サーバー)を追加すれば

パフォーマンス向上が見込めるため、対象のタスク処理のみを切り離すような設計になる。

 

Activity Workerのタスクに対するポーリング先を複数にすることで

異なるWorkflowの共通タスクを同一Workerが処理することも可能。

例えば、Excel形式での帳票出力ワークフローAとPDF形式の帳票出力ワークフローBがあり、

どちらも格納先はS3である場合、S3にアップロードするというタスクが共通なので、

あるActivity WorkerがワークフローA,Bに対するS3アップロードというタスクを兼任することが容易にできるということ。

 

ということで、概要等の説明はここまでで、次回は実際にApex(force.com)を使ってSWFを操作してみます!

実際に触ってみたほうが理解が早いです!!

 

※SWFの用語について

例のごとく用語がたくさんあります…。

主な用語を自分なりにわかりやすく書くとこんな感じ↓

■Actor

SWFのアクションを行うサーバやアプリのこと。

 

■Starter

ワークフローをスタートするActor(一番最初にTaskListに登録する)

 

■Decider

ビジネスロジックを担当するActor。

 

■Activity Worker(Worker)

タスク処理を担当するActor。

 

■TaskList

DeciderとActivity Workerのタスクの格納場所。

DeciderはDecision TaskListからタスクを受け取り、次の処理がある場合にはActivity TaskListにタスクを登録する。

Activity WorkerはActivity TaskListからタスクを受け取り

処理結果をSWFに返して、Decision TaskListにタスクを登録する。(SWFが自動的に登録してくれる)

Decider TaskListとActivity TaskListで完全に分けられてるっぽく

それぞれ同じ名前を指定しても異なる場所に格納されてるような挙動になる。

 

■Decision TaskList

Decider用のタスク。

Decisionはこのタスクを受け取ったら、ビジネスロジックに応じて

次に行うべきActivity Taskをスケジュールしたり、ワークフローを終了させたりする。

 

■Activity TaskList

Activity Worker用のタスク。

Activity Workerはこのタスクを受け取ったら、Activity Typeに応じた処理を行う。

 

■Domain

Workflowを束ねる単位。

DomainとWorkflow Type、Activity Typeはそれぞれワークフローの管理者が登録する。

 

■Workflow Type

その名の通り一連のワークフローの種類。

[データからPDFを生成して、S3にアップロードする]という処理があれば

それが1つのWorkflow Typeになる。

 

■Activity Type

タスク処理のタイプ。

データからPDFを生成して、S3にアップロードするというワークフローの場合

[データからPDFを生成][S3にアップロード]というのがそれぞれのタスク処理のタイプになる。

つまりタスク処理のタイプは疎結合になるように細分化しないとダメ。

© 2017 freedom-man.com

Theme by Anders NorenUp ↑