S3のファイル作成時にSNSからメールが2通飛んでしまう
解決済
回答 2
投稿
- 評価
- クリップ 0
- VIEW 1,381
前提・実現したいこと
S3のファイルがアップロードされたタイミングでJSONのファイル名に該当する
DynamoDBのテーブルにJSONデータを書き込むLambdaFunctionを作成しています。
DynamoDBのテーブルにデータの書き込みが完了したタイミングでSNS経由でメールを
送信するようにしたいと考えております。
発生している問題
何とかSNS経由でメール送信するところまではできたのですが、S3にファイルをアップロードした
際に1通しか送信されないはずのメールが2通送信されてきてしまいます。
どの様に処理すれば処理が完了したタイミングで1通のメールが送信されるというように
できるでしょうか。
ご教示のほどお願いいたします。
該当のソースコード
import logging
import boto3
import json
import os
import urllib
import datetime
LOGGER = logging.getLogger()
LOGGER.setLevel(logging.INFO)
dynamodb = boto3.resource('dynamodb')
s3_res = boto3.resource('s3')
s3_cl = boto3.client('s3')
# Write DynamoDB
def put_item(writeitems,writetable):
try:
table = dynamodb.Table(writetable)
with table.batch_writer() as batch:
for i in range(len(writeitems)):
batch.put_item(
Item=writeitems[i]
)
LOGGER.info("Completed registration")
return "end"
except Exception as e:
LOGGER.error(e)
raise e
def translateJson(res):
try:
s=json.loads(res.decode('utf-8-sig'))
return s
except Exception as e:
LOGGER.error(e)
raise e
# send message
def sendmessage(subject,msg):
try:
sqs_arn = os.getenv('SQS_ARN')
client = boto3.client('sns')
request = {
'TopicArn': sqs_arn,
'Message': msg,
'Subject': subject
}
r = client.publish(**request)
return r
except Exception as e:
LOGGER.error(e)
raise e
# main
def lambda_handler(event, context):
try:
bucket_name = os.getenv('BUCKET_NAME')
rep = s3_res.Bucket(bucket_name).objects.all()
mg = ''
for all_object in rep:
file_name = all_object.key
table_name=('.').join(file_name.split('.')[:-1])
response = s3_cl.get_object(Bucket=bucket_name, Key=file_name)
tabledata = response['Body'].read()
objItem = translateJson(tabledata)
stat = put_item(objItem,table_name)
LOGGER.info("Completed registration")
mg= mg + table_name + '\n'
else:
sb=u'Complete'
cd = datetime.datetime.now()
mg= mg + '\n' + u'EndTime:' + str(cd)
sendmessage(sb,mg)
return "end"
except Exception as e:
LOGGER.error(e)
sb=u'ERROR'
sendmessage(sb,e)
raise e
試したこと
Lambdaのエディタで「テスト」とした場合は1通だけメールが送信されます。
S3にファイルをアップした際にメールが2通飛んできます。
- Lambdaでテスト送信されるメール
item-content
item
EndTime:2018-11-27 02:24:14.801696
- S3にファイルをアップロードした際に送信されるメール
-- 1通目
item-content
EndTime:2018-11-27 02:27:26.662573
--2通目
item-content
item
EndTime:2018-11-27 02:27:27.544248
補足情報(FW/ツールのバージョンなど)
該当コードはLambdaのエディタで作成
python3.6
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
+1
具体的な解決策の提示ではありませんが
Lambdaは処理失敗時に実行条件に応じて、再試行を行います。
その際、デッドレターキュー(DLQ)を設定していれば
再試行したか否か解ると思いますので、試してみてはいかがでしょうか?
https://dev.classmethod.jp/cloud/aws/lambda-supports-dead-letter-queue/
以前、AWS IoT -> Lambda -> DynamoDBという処理フローで、ログの重複が発生し
調査したのですが、Lambda処理時、データ上は、1度目の処理は上手くいっているようなのですが
実際Lambdaは処理失敗判定となっており、再試行が走り、ログの重複が発生したという経験があります。
もし、参考になるのであればと思い投稿させて頂きました。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
check解決した方法
0
別件でしばらく別の作業をしていて解決が少し遅くなりましたが
自己解決しました。
そもそもの話ですが、複数ファイルのアップロードが完了してからLambdaが
起動されると考えていたのですが、そうではなくてS3にファイルがアップロード
された都度、トリガーが動いてLambdaが起動するみたいです。
なので以下の動きなので、自分の想定ミスです。初歩的なことですいません。
(1)1個目のitem.jsonのアップロード完了→Lambda起動
(2)2個目のitem-content.jsonのアップロード完了→Lambda起動
そのため、SNSでの通知が2回行われる結果となってしまいました。
※メールが2通届いて当然です。
そこでバッチ処理とはなりますが10分に1回程度処理ができれば問題ないので
トリガーをCloudWatchEventに変更して対処いたしました。
スケジュール式: cron(0/10 * ? * MON-FRI *)
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.22%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2018/11/28 09:57
2018/12/06 15:55
ふっと冷静に考えてみると、そうだよなぁとなるんですが離れてみないと気付かないものです。
本当にありがとうございました。m(__)m
2018/12/08 13:07
一度、距離を置いてから見直すと、結構自分で気づいてしまう事ってあるあるですよね。
開発頑張ってください👍