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における発表と協賛企業としてブースを出展
ファーエンドテクノロジーからのお知らせ(2025/01/15更新)
「しまね移住の先輩セミナー ~未経験からはじめるIT移住~」に弊社社員の呂 勝男が登壇
「しまね移住の先輩セミナー ~未経験からはじめるIT移住~」に、ファーエンドテクノロジー社員の呂勝男が登壇いたします。
オープンソースカンファレンス2025 Osakaに弊社代表の前田が登壇(ブース出展あり)
2025年1月25日に開催されるオープンソースカンファレンス2025 Osakaで、弊社代表の前田によるセミナー発表とブース出展を行います。
プロジェクト管理ツール「RedMica」バージョン 3.1.0をリリース Redmine互換のオープンソースソフトウェア
ファーエンドテクノロジー株式会社は、2024年11月19日(日本時間)、Redmine互換のプロジェクト管理ソフトウェア「RedMica 3.1.0」をリリースしました。
プロジェクト管理ツールRedmineのクラウドサービス「My Redmine」の海外向けサービス「My Redmine Global Edition」の提供を開始
「My Redmine」の海外向けサービスとして、新たに「My Redmine Global Edition」の提供を開始しました。
Redmineの最新情報をメールでお知らせする「Redmine News」配信中
新バージョンやセキュリティ修正のリリース情報、そのほか最新情報を迅速にお届け