最近やっている仕事で先日発表されたS3 Event Notificationsが利用出来そうな感じがしたのでちょっと調査。
S3にファイルがアップされたらAmazon SQSで通知を受け取るようにしてみた。
S3 => SNS => SQS
への通知は解説しているサイトが結構あるんですが、S3 => SQS
への通知設定の
情報が見当たらなかったので、動くようになるまで、いろいろと試行錯誤を繰り返した。
特にSQSのPermission設定が恐ろしく分かりにくくに2日くらいハマったので、自分用にメモしておく。
S3 Bucketの作成
S3でBucketを作成。既存Bucketを利用する場合はここはSKIP。
今回は検証用にglidenote-sqs-test
という名前でBucketを作成
SQSの設定
S3のイベント通知を受け取るQueueを作成する
Queue名をsqs-test
をして作成。
Add a Permission
をクリックして通知の受信元を設定する。
下記のように設定して、Add Condition
を選択
- Valueには
arn:aws:s3:::{S3のBucket名}
を設定
Actions部分はSendMessage
だけ選択して、Add Permission
を選択
こんな感じの設定になっていることを確認
S3 Event Notificationsの設定
S3のイベント通知をSQSに送るように設定。下記の例ではPUT
とPOST
イベントのみSQSに通知するように設定
正しく設定が出来ると下記のようになる。SQSのパーミッション設定が上手くてきていないとエラーになる。
実際にS3 EventをSQSで受け取る
下記のようなrubyのスクリプトを用意してSQSでイベントを受信してみる
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| #!/usr/bin/env ruby
# -*- coding: utf-8 -*-
require 'aws-sdk'
AWS.config(
:access_key_id => 'your_access_key_id',
:secret_access_key => 'your_secret_access_key',
:sss_endpoint => 'sqs.ap-northeast-1.amazonaws.com'
)
url = 'https://sqs.ap-northeast-1.amazonaws.com/xxxxxxxxxxxx/sqs-test'
sqs = AWS::SQS.new
while true
receive = sqs.queues[url].receive_message()
if receive
puts receive.body
receive.delete
sleep 1
end
puts "Waiting"
sleep 1
end
|
するとほぼリアルタイムで下記のような感じでイベントを受信出来る
1
| {"Records":[{"eventVersion":"2.0","eventSource":"aws:s3","awsRegion":"ap-northeast-1","eventTime":"2014-11-20T06:16:39.474Z","eventName":"ObjectCreated:Put","userIdentity":{"principalId":"AWLW0VGTI46AA"},"requestParameters":{"sourceIPAddress":"10.115.144.24"},"responseElements":{"x-amz-request-id":"E1C0A0C1F42CAA54","x-amz-id-2":"0p2FzYuEkiyaZn/n33XJLYjE3cmePkiqEFF5NMYy+c1PSGTNfmUf+Msou4Mejnr0"},"s3":{"s3SchemaVersion":"1.0","configurationId":"S3TestNotification","bucket":{"name":"glidenote-sqs-test","ownerIdentity":{"principalId":"AWLW0VGTI46AA"},"arn":"arn:aws:s3:::glidenote-sqs-test"},"object":{"key":"shindel.png","size":794485,"eTag":"b52627268c0e9071be00c5a38fdbc912"}}}]}
|
リアルタイムでS3のイベントを受信するにはSQSと常時通信しているために
Supervisordなどを用いてスクリプトを動かす必要があり。
これでリアルタイムな処理に対応が出来るようになった。ちょっと現在やってるタスクに適用出来るかしばらく検証してみる。
参考