- モチベーション
- AWS Step Functions とは
- 郷で Activity Worker を実装
— Activity
— 参考
— コード
— こうやって使うことを想定 - Demo
— Activity Worker を動かす環境
— State Machine: ビジュアルワークフロー
— State Machine: コード
— State1 : Godesu1 で実行するコマンド
— State2 : Godesu2 で実行するコマンド
— State Machine の実行 - ということで
どうも、郷です。
モチベーション
- むかーし、むかーし、1 台の EC2 cron で動かしている複数のバッチ処理があったとさ
- 村人(むらびと)たちはバッチ処理を動かす時だけ EC2 を起動したいと考えたとさ
- 村人たちの思いを汲んだ禿兵衛は EC2 は Lambda で起動してから、バッチを実行しようと考えたとさ
- ところが、禿兵衛は EC2 が正常に起動したことを正確に判断したり、バッチ処理の重複起動やハンドリングに頭を悩ましておりましたさ
そして、ちゃんと前後の処理をハンドリングしつつ、処理の流れをコード化(可視化)出来ればなあと黄昏れておりましたら…山の向こうから「AWS Step Functions というツールがあるばってん、こんツールはくさ、Activity を使えばくさ、EC2 やオンプレのタスクも制御出来るちゃんねー」という声を聞くのであった…
ということで、EC2 で動かしているバッチ処理を Activity で制御することを想定して、Golang で Worker を実装して Acitivity の挙動についてチュートリアルしてみたメモでござる。
AWS Step Functions とは
aws.amazon.com
Step Functions の詳しい説明については、以下の資料がとても参考になりました。
有難うございます!!
郷で Activity Worker を実装
Activity
docs.aws.amazon.com
Activities are an AWS Step Functions concept that refers to a task to be performed by a worker that can be hosted on EC2, ECS, mobile devices—basically anywhere.
超ざっくりだけど…
- Activity とは EC2 や ECS 等、オンプレミスのサーバーでも動く Worker によって実行されるタスクのこと
- AWS SDK や AWS CLI で Worker を実装出来る
- Worker は Activity の ARN を指定して起動すると Activity に対してポーリングを行う
Activity は AWS CLI では以下のように作成します。
$ aws \ --profile oreno-profile --region ap-northeast-1 \ stepfunctions create-activity \ --name=OrenoActivity
以下のように出力されます。
{ "creationDate": 1500076193.843, "activityArn": "arn:aws:states:ap-northeast-1:012345678912:activity:OrenoActivity" }
State Machine には以下のように指定します。
{ "Comment": "Golang Demo", "StartAt": "Godesu1", "States": { "Godesu1": { "Type": "Task", "Resource": "arn:aws:states:ap-northeast-1:012345678912:activity:OrenoActivity", "Next": "wait_using_seconds" } } }
参考
こちらやこちらを目一杯参考にさせて頂きました。有難うございます!!
コード
こうやって使うことを想定
./taskRunner -arn=${Activity ARN} -command=${実行したいコマンド}
Demo
Activity Worker を動かす環境
$ sw_vers ProductName: Mac OS X ProductVersion: 10.11.6 BuildVersion: 15G1421 $ go version go version go1.8.3 darwin/amd64 $ go build taskRunner.go
State Machine: ビジュアルワークフロー
State Machine とは State をつなげたフローのことで、以下のようなフローで動かしてみます。
State Name | State Type | State で実行したいコマンド |
---|---|---|
Godesu1 | Task | demo01.sh |
wait_using_seconds | Wait | 10 秒待ってから State: Godesu2 を実行 |
Godesu2 | Task | demo02.sh |
State Machine: コード
{ "Comment": "Golang Demo", "StartAt": "Godesu1", "States": { "Godesu1": { "Type": "Task", "Resource": "arn:aws:states:ap-northeast-1:123456789012:activity:OrenoFirstActivity", "Next": "wait_using_seconds" }, "wait_using_seconds": { "Type": "Wait", "Seconds": 10, "Next": "Godesu2" }, "Godesu2": { "Type": "Task", "Resource": "arn:aws:states:ap-northeast-1:123456789012:activity:OrenoSecondActivity", "End": true } } }
State1 : Godesu1 で実行するコマンド
$ cat demo01.sh #!/usr/bin/env bash for i in $(seq 1 2 10); do echo $i done
Activity Worker を以下のように実行して待機させておきます。
./taskRunner -arn=arn:aws:states:ap-northeast-1:123456789012:activity:OrenoFirstActivity -command="./demo01.sh"
以下のように出力されます。
$ ./taskRunner -arn=arn:aws:states:ap-northeast-1:123456789012:activity:OrenoFirstActivity -command="./demo01.sh" 2017/07/15 08:00:49 taskRunner Started.
State2 : Godesu2 で実行するコマンド
$ cat demo02.sh #!/usr/bin/env bash for i in $(seq 2 2 10); do echo $i done
Activity Worker を以下のように実行して待機させておきます。
./taskRunner -arn=arn:aws:states:ap-northeast-1:123456789012:activity:OrenoSecondActivity -command="./demo02.sh"
以下のように出力されます。
$ ./taskRunner -arn=arn:aws:states:ap-northeast-1:123456789012:activity:OrenoSecondActivity -command="./demo02.sh" 2017/07/15 08:00:55 taskRunner Started.
State Machine の実行
以下のように AWS CLI で実行します。
$ aws \ --profile oreno-profile --region ap-northeast-1 \ stepfunctions start-execution \ --state-machine-arn=arn:aws:states:ap-northeast-1:012345678912:stateMachine:DemoStateMachine-Go-3
以下のようにレスポンスが返ってきます。
{ "startDate": 1500075053.349, "executionArn": "arn:aws:states:ap-northeast-1:012345678912:execution:DemoStateMachine-Go-3:859949c4-b3a4-4b7c-84ed-60f555e859e6" }
そして、それぞれの Activity Worker では以下のように出力されています。
それぞれ別の Activity を利用しているので、順番も制御出来ている(Godesu1 → Godesu2 の順番)ことが判ります。
マネジメントコンソールでも上図のように State Machine の処理が正常に終了していることが判ります。
このフロー図を見ているだけでウキウキしますね。
ということで
Step Functions = Lambda という印象がありましたが、Activity を使うことで従来のバッチ処理等について変更を最小限に処理フロー(State Machine)に組み込めるのはとても嬉しいです。しかし、こちらでも言及されている通り、Activity は Worker を実装する必要があったり、Worker の運用管理が必要になる点は注意が必要です。
今回、禿兵衛の目の前にあるシチュエーションの場合、Activity Worker は EC2 が起動したタイミングで必ず起動することを保証する必要があったりしますが、それ自体も State の一つとして Lambda ファンクションに組み込んでしまうのもありかなと思ったりしています。
Step Functions とても面白いサービスで好きになっちゃいました。