最近、疎結合なシステム構築のためのサービスである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にアップロード]というのがそれぞれのタスク処理のタイプになる。

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