AWSを使用したメール通知処理を改善しています


My Redmine

原田です。今回は業務で利用している社内メールが送信されないことがありましたので調べてみました。

フォームへの入力を集計してメールで通知

AWS上に構築したフォームに入力があると、それらを集計して毎朝通知するメール処理を行っています。

通知が送られないことが時々あります

この通知機能をリリースした時は毎日通知していましたが、いつの頃か通知されない日が不定期に発生しました。(業務には直接影響しない通知なのでこの不具合を放置していましたが)改善したいと思い調べることにしました。

通知機能を実行しているステートマシンを確認

まずは通知処理を実行しているステートマシン(AWS Step Functions)の実行状況を確認しました。不定期に失敗している様子が伺えます。


ステートマシンの実行状況

ステートマシンは以下の流れで各処理を実施していますが、「Get log」が赤く表示されて失敗していることが分かります。 この画面ではエラーメッセージなども確認できます。


ステートマシンの処理フロー

失敗しているLambdaでは何してる?

「Get log」で実施しているGetlog*****はRubyで作成したAWS Lambdaです。このLambdaでは以下の処理を実施しています。

プログラムのことをご存知の方には難しいことをしているように見えないと思います。ただし上記イメージに記載されているエラーメッセージRate exceededは、AWSサービスのAPIを短時間に大量に呼び出している時に発生するエラーです。

そこでCloudWatchサービスに定義されているクォータ(制限値)を確認しました。Getlog*****で使用しているAPIはDescribeLogStreamsGetLogEventsで、これらAPIを(条件に一致するログを取得するため)繰り返し呼び出しています。


CloudWatchサービスのクォータ

Lambdaの失敗が不定期に発生しているので、「Getlog*****で実施しているAPIリクエストの呼び出し回数が(ログストリームやログイベントの量によって)クォータを超えたためRate exceededが発生しているのかも」と思いました。

Lambdaの改善

短時間でAPIを呼び出していることが原因のようなので、sleepメソッドを組み込むことでAPI呼び出しを待たせることにしました。

  loop do
    resp_streams = client.describe_log_streams(param_streams)
    resp_streams.log_streams.each do |log_stream|
      ...

      loop do
        resp_events = client.get_log_events(param_events)
        resp_events.events.each do |event|
          ...

          # ログを取得
       end

        break if resp_events.next_forward_token == param_events[:next_token]
        param_events[:next_token] = resp_events.next_forward_token
        sleep(0.3)
      end
    end

    break unless resp_streams.next_token
    param_streams[:next_token] = resp_streams.next_token
    sleep(0.3)
  end

ステートマシンの改善

サービスクォータはAWSアカウントごとに定義されています。同時間帯に別の処理で同じようなことを実施するとRate exceededが発生することもあり得ます。そこでステートマシンにリトライ処理(Exponential Backoff)を組み込みます。


ステートマシンにリトライ処理を追加

AWSは様々なサービスが連携しているので待たせることも必要かも

上記の改善はまだ動作確認をしていませんのでリリースは少し先になりますが、うまく動作すると信じています。今回の改善で以下のことが分かりました。

【スタッフ募集中】
弊社ではAWSを活用したソリューションの企画・設計・構築・運用や、Ruby on Rails・JavaScriptフレームワークなどを使用したアプリケーション開発を行うスタッフを募集しています。採用情報の詳細
弊社での勤務に関心をお持ちの方は、知り合いの弊社社員・関係者を通じてご連絡ください。

My Redmine

こちらの記事もオススメです!
My Redmine Gen.2 ログダウンロード機能を改善しています
My Redmineのログダウンロード機能のログファイルが解凍できない事象を改善。
Redmine My Pageの使いこなし
RedmineのMy Page機能で利用者ごとのダッシュボードが作れます
台湾のオープンソースイベント COSCUP 2023に参加
台湾で開催されたCOSCUP 2023に初めて参加
中国語初級者が台湾のCOSCUPでの発表をやりきるためのスライドづくり
台湾で開催されたCOSCUP 2023というオープンソースのイベントでRedmineの発表を中国語で行いました
オフライン初開催「Redmine Japan Vol.3」参加レポート
Redmine Japan Vol.3における発表と協賛企業としてブースを出展
ファーエンドテクノロジーからのお知らせ(2024/04/24更新)
入門Redmine 第6版 出版記念企画セミナー「Redmineのアクセス制御」【2024/5/30開催】
入門Redmine 第6版(2024年3月23日発売)の書籍から「Redmineのアクセス制御」について解説します。
My Redmine 初回ご契約で「入門Redmine 第6版」プレゼントのお知らせ
Redmineのクラウドサービス「My Redmine」を初めてご契約いただいたお客様にRedmine解説書「入門Redmine 第6版」を進呈いたします。
2024年度ブランドパートナーに島根県在住のモデル ユイさんを継続起用
ユイさん(モデルスタジオミューズ所属)をファーエンドテクノロジーの2024年度ブランドパートナーとして継続して起用します。
My Redmine スタンダードプランおよびAdminサポートデスクプランの料金改定のお知らせ【2024年4月ご利用分より】
2024年4月ご利用分より、My Redmine スタンダードプラン(民間企業・個人向け及び官公庁向け)とAdminサポートデスクプランの料金を改定いたします。
Redmineの最新情報をメールでお知らせする「Redmine News」配信中
新バージョンやセキュリティ修正のリリース情報、そのほか最新情報を迅速にお届け